How to get all controls from a form at runtime in C#?
Is there a simple way to get all controls that contains the property ".Text"
?
I'm able to get all "top level"
controls, but my code doesn't find sub controls like menu item开发者_如何学Pythons
on all levels, etc. I also tried "ctrl.HasChildren"
.
How do I do this in Windows Forms at runtime?
Every control that derives from Control has a Text property, which is every control — however for some controls this property does not have a meaning.
To build the complete list of controls you need to iterate the Form's Controls collection and then, for each control within it, recursively iterate that control's Controls collection.
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);
}
}
I'm not actually sure how you are going to differentiate between controls that have a useful Text property and those for which it is not used. Obviously one approach would be to exclude those controls that have an empty string for the Text property.
One can also do something similar for the menu (note that you will need to modify this somewhat if you are using the 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);
}
}
You could loop through each control and use reflection to find the property Name Text
foreach (Control contrl in this.Controls)
{
if (contrl.GetType().GetProperty("Text") != null)
{
// contrl has Text Property
}
}
Adding in the search for all controls
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);
}
}
}
You should be able to check
if(control.Controls.Count > 0)
With this you can then recursively call your method to loop down the control tree.
Recursion might be a solution, having a function which takes a control and returns all of its children (which calls itself on all children).
That way you'd get a flat array of controls.
精彩评论