[英]Iterating through textbox controls in a panel C#
I have seen many others with similar problems but I cannot find the flaw in my logic here. 我看到许多其他人也遇到类似的问题,但是我在这里找不到逻辑上的缺陷。 Any help would be greatly appreciated. 任何帮助将不胜感激。
I have a Panel which I have added numerous label and textbox controls to, ie: 我有一个面板,其中添加了许多标签和文本框控件,即:
myPanel.Controls.Add(txtBox);
These controls are created and added in a method called previous to the iteration method. 这些控件是在迭代方法之前的方法中创建和添加的。
I want to iterate through each textbox and use its Text property as a parameter in another method but I am not having any luck. 我想遍历每个文本框,并在另一种方法中将其Text属性用作参数,但是我没有任何运气。 Here is my attempt to iterate: 这是我的尝试:
public void updateQuestions()
{
try
{
foreach (Control c in editQuestionsPanel.Controls)
{
if (c is TextBox)
{
TextBox questionTextBox = (TextBox)c;
string question = questionTextBox.Text;
writeNewQuestionToTblQuestions(question);
}
}
}
catch (Exception err)
{
Console.WriteLine(err.Message);
}
}
The problem I am having is that the controls are not in the Panel when I arrive at this updateQuestions() method. 我遇到的问题是,当我到达此updateQuestions()方法时,控件不在面板中。 Here is the process involved: 这是涉及的过程:
A commandButton is clicked and the questions are read from a DB, for each question a method is called which adds 2 labels and a textbox to editQuestionsPanel.Controls. 单击一个commandButton,然后从数据库中读取问题,对于每个问题,将调用一个方法,该方法为editQuestionsPanel.Controls添加2个标签和一个文本框。 This panel is inside a PlaceHolder which is then made visible. 该面板位于PlaceHolder内部,然后将其显示。
When a button inside the PlaceHolder is clicked, the updateQuestions() method is called and the editQuestionsPanel.Controls.Count = 1. As there are approx 12 questions in the DB it should be around 36. The one control inside the Panel is of type: 单击PlaceHolder内的按钮时,将调用updateQuestions()方法,并且editQuestionsPanel.Controls.Count =1。由于DB中大约有12个问题,因此该问题应约为36个。Panel中的一个控件的类型为:
System.Web.UI.LiteralControl
It contains no controls. 它不包含任何控件。
I am sure that somwhere in the lifecycle the Panel's controls are being cleared but I do not know how to step thru the life cycle. 我敢肯定,在生命周期中的任何地方都已清除了面板的控件,但我不知道如何跨过生命周期。 I have a Page_load method which is called as soon as a button is clicked but once the button which calls updateQuestions() is clicked the editQuestionsPanel.Controls.Count is already back to 1 so it must be cleared before this but I do not know how to correct this... 我有一个Page_load方法,单击按钮后立即调用,但是一旦单击调用updateQuestions()的按钮,editQuestionsPanel.Controls.Count已经恢复为1,因此必须在此之前清除它,但我不知道如何纠正这个...
Any help you can give to help me solve this would be greatly appreciated - its killing me! 您能提供的任何帮助我解决此问题的帮助将不胜感激-它杀死了我!
This selects from collection controls only that which are of type TextBox. 这仅从集合控件中选择TextBox类型的控件。
(the same as control is TextBox
or (control as TextBox) != null
) (与control is TextBox
相同为control is TextBox
或(control as TextBox) != null
)
If controls are contained in editQuestionsPanel.Controls
: 如果控件包含在editQuestionsPanel.Controls
:
using System.Linq;
IEnumerable<TextBox> textBoxes = editQuestionsPanel.Controls.OfType<TextBox>();
foreach (TextBox textBox in textBoxes)
{
// do stuff
}
To select all child controls use next extension method: 要选择所有子控件,请使用下一个扩展方法:
public static IEnumerable<T> GetChildControls<T>(this Control control) where T : Control
{
var children = control.Controls.OfType<T>();
return children.SelectMany(c => GetChildControls<T>(c)).Concat(children);
}
Using: 使用方法:
IEnumerable<TextBox> textBoxes = editQuestionsPanel.GetChildControls<TextBox>();
When you add controls dynamically, you need to do that on every request - asp.net doesn't do that for you! 动态添加控件时,需要在每个请求上都执行此操作-asp.net不会为您执行此操作!
Add the controls in the Init or Load phase, then they will get populated with the postback values. 在Init或Load阶段添加控件,然后将使用回发值填充控件。
A frequently made mistake: Container.Controls
only contains the first level child controls in this container. 一个常见的错误: Container.Controls
仅包含此容器中的第一级子控件。 That is: TextBox1 in PanelA, PanelA in PanelB, you can't get TextBox1 in PanelB.Controls. 即:PanelA中的TextBox1,PanelB中的PanelA,您无法在PanelB.Controls中获得TextBox1。
My solution is to write an extension method: 我的解决方案是编写一个扩展方法:
public static IEnumerable<Control> AllControls(this Control ctl)
{
List<Control> collection = new List<Control>();
if (ctl.HasControls())
{
foreach (Control c in ctl.Controls)
{
collection.Add(c);
collection = collection.Concat(c.AllControls()).ToList();
}
}
return collection;
}
Now TextBox1 is in PanelB.AllControls()
. 现在TextBox1在PanelB.AllControls()
。 To filter all controls with type, using PanelB.AllControls().OfType<TextBox>()
若要使用类型筛选所有控件,请使用PanelB.AllControls().OfType<TextBox>()
Try this 尝试这个
int Count = 0;
foreach (Control ctr in Panel1.Controls)
{
if (ctr is TextBox)
Count++;
}
You can do something like this instead: 您可以改为执行以下操作:
var questions = from tb in editQuestionsPanel.Controls.OfType<TextBox>()
select tb.Text;
foreach(var question in questions)
{
writeNewQuestionToTblQuestions(question);
}
If the other answers don't help, try doing your code but add recursivity. 如果其他答案没有帮助,请尝试编写代码,但增加递归性。 Your code would not work if it's editQuestionsPanel => Panel => Textbox 如果代码是editQuestionsPanel => Panel => Textbox,则您的代码将不起作用
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.