如何让父母控制的所有孩子?

时间:2011-12-21 19:46:53

标签: c# .net controls

我正在寻找一个代码示例,如何获取父控件的所有子代。

我不知道怎么做。

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

5 个答案:

答案 0 :(得分:19)

如果您只想要直系孩子,请使用

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

如果您想要层次结构中的所有控件(即树中某些控件下的所有控件),请使用:

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

    }

然后,你可以在表格中使用这样的东西:

    private void button1_Click(object sender, EventArgs e)
    {
        /// get all of the controls in the form's hierarchy in a List<>
        var controlList = GetControlHierarchy(this).ToList();

        foreach (var control in controlList)
        {
            /// do something with this control
        }
    }

请注意,.ToList()将立即评估整个Enumerable,这消除了您从协同程序实现中获得的任何性能优势。

答案 1 :(得分:4)

控件有一个MyControl.Controls集合,你可以foreach开启。

每个Control还有一个Parent属性,可以为您提供父控件。

如果您需要降低未知数量的级别,可以编写递归方法。

答案 2 :(得分:2)

也许这对某人有用:

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

这是递归函数,用于获取可能应用过滤器的控件集合(按类型进行示例)。例如:

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

它将返回rootControl中的所有DropDownLists及其所有子项

答案 3 :(得分:0)

可能过于复杂,但使用Linq和上面/其他地方的一些想法:

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

答案 4 :(得分:0)

这是一个使用 Linq 的简洁递归扩展函数:

        /// <summary>
        /// Recursive function to get all descendant controls.
        /// </summary>
        public static IEnumerable<Control> GetDescendants(this Control control)
        {
            var children = control.Controls.OfType<Control>();
            return children.Concat(children.SelectMany(c => GetDescendants(c)));
        }