简体   繁体   English

遍历面板C#中的文本框控件

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM