Как получить все элементы управления из формы во время выполнения в C #? - PullRequest
0 голосов
/ 30 ноября 2009

Есть ли простой способ получить все элементы управления, которые содержат свойство ".Text"?

Я могу получить все "top level" элементы управления, но мой код не находит суб-элементы управления, такие как menu items на всех уровнях и т. Д. Я также пытался "ctrl.HasChildren".

Как мне сделать это в Windows Forms во время выполнения?

Ответы [ 4 ]

7 голосов
/ 30 ноября 2009

Каждый элемент управления, производный от элемента управления, имеет свойство Text, то есть каждый элемент управления, однако для некоторых элементов управления это свойство не имеет значения.

Чтобы создать полный список элементов управления, вам нужно выполнить итерацию коллекции Controls формы, а затем, для каждого элемента управления внутри нее, рекурсивно повторить коллекцию Controls этого элемента управления.

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

На самом деле я не уверен, как вы собираетесь различать элементы управления, которые имеют полезное свойство Text, и элементы управления, для которых оно не используется. Очевидно, один из подходов состоит в том, чтобы исключить те элементы управления, которые имеют пустую строку для свойства Text.

Можно также сделать что-то подобное для меню (обратите внимание, что вам нужно будет немного изменить это, если вы используете 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);
    }
}
3 голосов
/ 30 ноября 2009

Вы можете перебрать каждый элемент управления и использовать отражение, чтобы найти свойство Имя Текст

     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);
        }
     }
  }
1 голос
/ 30 ноября 2009

Вы должны быть в состоянии проверить

if(control.Controls.Count > 0)

После этого вы можете рекурсивно вызывать ваш метод для зацикливания дерева управления.

0 голосов
/ 30 ноября 2009

Рекурсия может быть решением, имеющим функцию, которая принимает элемент управления и возвращает все его дочерние элементы (который вызывает себя для всех дочерних элементов).

Таким образом, вы получите плоский массив элементов управления.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...