aron
aron

Reputation: 2886

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

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!

Upvotes: 4

Views: 11179

Answers (5)

JasShep
JasShep

Reputation: 21

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]);
        }
    }

Upvotes: 2

Ron Warholic
Ron Warholic

Reputation: 10074

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.

Upvotes: 8

ChrisF
ChrisF

Reputation: 137148

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.

Upvotes: 1

Grzenio
Grzenio

Reputation: 36649

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);
    }
}

Upvotes: 2

Matt
Matt

Reputation: 4117

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

there is a sample Here

Upvotes: 4

Related Questions