foreach Control ctrl in SomePanel.Controls does not get all controls

10,880

Solution 1

Here's a lazy solution:

public IEnumerable<Control> GetAllControls(Control root) {
  foreach (Control control in root.Controls) {
    foreach (Control child in GetAllControls(control)) {
      yield return child;
    }
  }
  yield return root;
}

Remember also that some controls keep an internal collection of items (like the ToolStrip) and this will not enumerate those.

Solution 2

You would need to recursively "treewalk" through the controls, think about it like walking through a folder structure.

there is a sample Here

Solution 3

As far as I know your have to implement the recursion yourself, but its not really difficult.

A sketch (untested):

void AllControls(Control root, List<Control> accumulator)
{
    accumulator.Add(root);
    foreach(Control ctrl in root.Controls)
    {
        AllControls(ctrl, accumulator);
    }
}

Solution 4

I had exactly the problem stated in the question so this may help somebody. I was attempting to clear a control collection prior to rewriting it.

private void clearCollection(Control.ControlCollection target)
{
    foreach (Control Actrl in target)
    {
        if (Actrl is Label || Actrl is Button)
        {
            target.Remove(Actrl);
        }
    }
 }

By removing the control inside the foreach loop it must mess with the internal pointers and the result is controls in the collection are missed. My solution was to find all the controls then remove in a separate loop.

private void clearCollection(Control.ControlCollection target)
    {
        List<Control> accumulator = new List<Control>();

        foreach (Control Actrl in target)
        {
            if (Actrl is Label || Actrl is Button)
            {
                accumulator.Add(Actrl);  // find all controls first. 
            }
        }

        for (int i = 0; i < accumulator.Count; i++)
        {
            target.Remove(accumulator[i]);
        }
    }

Solution 5

The reason is because the only controls that are direct children of your panel are the table and the literals you mention, and it is only these that this.pnlSolutions.Controls returns.

The text boxes an labels are child controls of the table, making them grandchildren of the panel.

As @Yoda points out you need to recursively walk the controls to find them all.

Share:
10,880
aron
Author by

aron

Updated on June 06, 2022

Comments

  • aron
    aron almost 2 years

    I have a panel with a bunch of labeles and textboxes inside of it.

    The code:

    foreach (Control ctrl in this.pnlSolutions.Controls)
    

    Seems to only be finding html table inside the panel and 2 liternals. But it does not get the textboxes that are in the html table. Is there a simple way to get all the controls inside of a panel regardless of the nesting?

    thanks!