How to get all children of a parent control?

2020-01-29 10:38发布

问题:

I'm looking for an code example how to get all children of parent control.

I have no idea how do it.

foreach (Control control in Controls)
{
  if (control.HasChildren)
  {
    ??
  }
}

回答1:

If you only want the immediate children, use

...
var children = control.Controls.OfType<Control>();
...

If you want all controls from the hierarchy (ie, everything in the tree under a certain control), use a pretty simple data-recursive method:

    private IEnumerable<Control> GetControlHierarchy(Control root)
    {
        var queue = new Queue<Control>();

        queue.Enqueue(root);

        do
        {
            var control = queue.Dequeue();

            yield return control;

            foreach (var child in control.Controls.OfType<Control>())
                queue.Enqueue(child);

        } while (queue.Count > 0);

    }

Then, you might use something like this in a form:

    private void button1_Click(object sender, EventArgs e)
    {
        /// get all of the controls in the form's hierarchy in a List<>
        foreach (var control in GetControlHierarchy(this))
        {
            /// do something with this control
        }
    }


回答2:

Controls have a MyControl.Controls collection which you can do a foreach on.

Each Control also has a Parent property which gives you the parent control.

You can write a recursive method if you need to go down an unknown number of levels.



回答3:

Maybe it could be useful for someone:

public void GetControlsCollection(Control root,ref List<Control> AllControls,  Func<Control,Control> filter)
{
    foreach (Control child in root.Controls)
    {
        var childFiltered = filter(child);
        if (childFiltered != null) AllControls.Add(child);
        if (child.HasControls()) GetControlsCollection(child, ref AllControls, filter);
    }
}

This is recursive function to get the collection of controls with the possibility of appling filter (for expample by type). And the example:

 List<Control> resultControlList = new List<Control>();
 GetControlsCollection(rootControl, ref resultControlList, new Func<Control,Control>(ctr => (ctr is DropDownList)? ctr:null ));

It will return all DropDownLists in rootControl and his all children



回答4:

Probably overly complicated, but using Linq and some ideas from above / other places:

    public static IEnumerable<Control> GetAllChildren(this Control root) {
        var q = new Queue<Control>(root.Controls.Cast<Control>());

        while (q.Any()) {
            var next = q.Dequeue();
            next.Controls.Cast<Control>().ToList().ForEach(q.Enqueue);

            yield return next;
        }
    }


标签: c# .net controls