首页 > 解决方案 > 获取一个类型的所有控件,包括嵌套容器

问题描述

我有一个带有多级容器设置的 winforms 项目。例如,我在顶层有一组面板,每个面板都有另一组嵌套在其中的面板,每个子面板都有一组控件(文本框、复选框等)。 .

我想要的是能够检索某种类型的控件,只给顶级面板。例如,在我的项目中使用名称的一组是MainPanelTruck,它下面有一个PanelTruckCheck面板,它本身有 8个CheckBox嵌套在其中。我希望能够检索CheckBox仅给出MainPanelTruck的那 8 个。

这是面板结构的一部分的图像以供参考。

我一直在努力OfType<>()工作,但据我所知,它只搜索下一层,所以当我搜索CheckBox使用它时,我什么也没得到,因为它只查看子面板。

如果该Find方法ControlCollection允许使用谓词或条件而不是特定字符串作为键,searchAllChildren这将容易得多,因为它具有 bool 在这里非常方便。

我可以想出很多方法可以在这里得到我想要的物品,但没有一个感觉特别优雅,这正是我在这里寻求的。谢谢 :)

标签: c#.netwinforms

解决方案


您可以编写一个简单的(扩展)方法来返回给定控件的所有嵌套控件:

public static class ControlExtensions
{
    public static IEnumerable<Control> GetAllNestedControls(this Control root)
    {        
        var stack = new Stack<Control>();
        stack.Push(root);

        do
        {
            var control = stack.Pop();

            foreach (Control child in control.Controls)
            {
                yield return child;
                stack.Push(child);
            }
        }
        while (stack.Count > 0);
    }
}

有了这个,获取所有复选框很容易:

panel1.GetAllNestedControls().OfType<CheckBox>()

如果需要,您还可以传递一个可选的布尔标志来搜索所有子项。在将子控件推送到堆栈之前检查标志。在这种情况下,我会将方法重命名为 00110001 建议的名称:

IEnumerable<Control> EnumerateControls(this Control root, bool searchAllChildren)

用法是

 panel1.EnumerateControls(searchAllChildren: true).OfType<CheckBox>()

推荐阅读