C# 在C语言中,如何在运行时从窗体获取所有控件?

C# 在C语言中,如何在运行时从窗体获取所有控件?,c#,.net,winforms,C#,.net,Winforms,是否有一种简单的方法可以获取包含属性.Text的所有控件 我能够获得所有顶级控件,但我的代码找不到所有级别上的子控件,如菜单项等。我还尝试了ctrl.HasChildren 如何在运行时在Windows窗体中执行此操作?您应该能够检查 if(control.Controls.Count > 0) 有了它,你可以递归地调用你的方法来循环控制树。递归可能是一种解决方案,它有一个函数,它接受一个控件并返回它的所有子控件,它在所有子控件上调用自己 这样,您将得到一个平面控件数组。从控件派生的每个

是否有一种简单的方法可以获取包含属性.Text的所有控件

我能够获得所有顶级控件,但我的代码找不到所有级别上的子控件,如菜单项等。我还尝试了ctrl.HasChildren


如何在运行时在Windows窗体中执行此操作?

您应该能够检查

if(control.Controls.Count > 0)

有了它,你可以递归地调用你的方法来循环控制树。

递归可能是一种解决方案,它有一个函数,它接受一个控件并返回它的所有子控件,它在所有子控件上调用自己


这样,您将得到一个平面控件数组。

从控件派生的每个控件都有一个文本属性,即每个控件-但是对于某些控件,此属性没有意义

要构建控件的完整列表,您需要迭代窗体的控件集合,然后,对于其中的每个控件,递归迭代该控件的控件集合

IList<Control> controlsOnForm = new List<Control>();
BuildControlsList(this.Controls, controlsOnForm);

private static void BuildControlsList(ControlCollection controls, IList<Control> listToPopulate)
{
    foreach (Control childControl in controls)
    {
        listToPopulate.Add(childControl);
        BuildControlsList(childControl.Controls, listToPopulate);
    }
}
实际上,我不确定如何区分具有有用文本属性的控件和未使用该属性的控件。显然,一种方法是排除那些文本属性为空字符串的控件

也可以对菜单执行类似操作。注意,如果使用MainMenuStrip,则需要对其进行一些修改:

IList<Menu> menusOnForm = new List<Menu>();
if (this.Menu != null)
{
    menusOnForm.Add(this.Menu);
    BuildMenuList(this.Menu.MenuItems, menusOnForm);
}

private static void BuildMenusList(MenuItemCollection menuItems, IList<Menu> listToPopulate)
{
    foreach (Menu menuItem in menuItems)
    {
        listToPopulate.Add(menuItem);
        BuildMenusList(menuItem.MenuItems, listToPopulate);
    }
}

可以循环遍历每个控件,并使用反射查找属性名文本

     foreach (Control contrl in this.Controls)
     {
        if (contrl.GetType().GetProperty("Text") != null)
        {
           // contrl has Text Property
        }
     }
在搜索中添加所有控件

  List<Control> text_controls = new List<Control>();
  FindAllControls(this.Controls, text_controls);

  private void FindAllControls(Control.ControlCollection controls, List<Control> ctrlsWithTextProperty)
  {
     foreach(Control ctrl in controls)
     {
        if(ctrl.GetType().GetProperty("Text") != null)
        {
           ctrlsWithTextProperty.Add(ctrl);
        }
        if (ctrl.Controls != null)
        {
           FindAllControls(ctrl.Controls, ctrlsWithTextProperty);
        }
     }
  }

控件不可能没有文本属性,因为它是控件类的成员,因此if语句的条件实际上是精心设计的true。@SwDevMan81:这与我的方法类似。但它找不到菜单项文本。对于简单控件,“ctrl.Controls”不为空。相反,它是System.Windows.Forms.Control.ControlCollection类型的空列表。因此,此示例代码会导致不必要的递归,如果为其他用途进行调整/调整,可能无法按预期工作。我认为必须显式处理菜单,因为它们不是从控件派生的,并且没有可以迭代的包含表单所有组件的“组件”集合。前提与上面的相同,但不是控制,而是迭代菜单项。我将更新答案以说明。您的代码看起来很棒,但此.Menu始终为空。我正在使用toolstipcontainer…您也应该能够将这些原则应用于此-您可以在循环中添加一行,检查控件是否为ToolStripContainer,然后递归地查看ToolStripMenuItems。除了ToolStripItem中似乎没有任何容器对象之外。