Reputation: 707
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 items
on all levels, etc. I also tried "ctrl.HasChildren"
.
How do I do this in Windows Forms at runtime?
Upvotes: 0
Views: 4890
Reputation: 11576
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.
Upvotes: 0
Reputation: 38620
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);
}
}
Upvotes: 7
Reputation: 50018
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);
}
}
}
Upvotes: 3
Reputation: 166536
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.
Upvotes: 1