Как получить все элементы управления формы в Windows Forms? - PullRequest
6 голосов
/ 29 апреля 2010

У меня есть Form с именем A.

A содержит множество различных элементов управления, включая основной GroupBox. GroupBox содержит множество таблиц и других GroupBox. Я хочу найти элемент управления, который имеет, например, индекс табуляции 9 в форме A, но я не знаю, какой GroupBox содержит этот элемент управления.

Как я могу это сделать?

Ответы [ 5 ]

13 голосов
/ 29 апреля 2010

с рекурсией ...

public static IEnumerable<T> Descendants<T>( this Control control ) where T : class
{
    foreach (Control child in control.Controls) {

        T childOfT = child as T;
        if (childOfT != null) {
            yield return (T)childOfT;
        }

        if (child.HasChildren) {
            foreach (T descendant in Descendants<T>(child)) {
                yield return descendant;
            }
        }
    }
}

Вы можете использовать вышеуказанную функцию как:

var checkBox = (from c in myForm.Descendants<CheckBox>()
                where c.TabIndex == 9
                select c).FirstOrDefault();

Это позволит получить первый CheckBox в любом месте формы с TabIndex, равным 9. Очевидно, вы можете использовать любой критерий, какой пожелаете.

Если вы не являетесь поклонником LINQ синтаксиса запроса, вышеприведенное можно переписать так:

var checkBox = myForm.Descendants<CheckBox>()
                     .FirstOrDefault(x=>x.TabIndex==9);
4 голосов
/ 29 апреля 2010

Рекурсивный поиск по элементам управления вашей формы collection.

void FindAndSayHi(Control control)
{
    foreach (Control c in control.Controls)
    {
        Find(c.Controls);
        if (c.TabIndex == 9)
        {
            MessageBox.Show("Hi");
        }
    }
}
2 голосов
/ 29 апреля 2010

Вы можете создать такой метод:

public static Control GetControl(Control.ControlCollection controlCollection, Predicate<Control> match)
{
    foreach (Control control in controlCollection)
    {
        if (match(control))
        {
            return control;
        }

        if (control.Controls.Count > 0)
        {
            Control result = GetControl(control.Controls, match);
            if (result != null)
            {
                return result;
            }
        }
    }

    return null;
}

... используется следующим образом:

Control control = GetControl(this.Controls, ctl => ctl.TabIndex == 9);

Обратите внимание, что TabIndex - сложный случай, поскольку он начинается с 0 в каждом контейнере, поэтому может быть несколько элементов управления в одной и той же форме, имеющих одинаковое значение TabIndex.

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

Control control = GetControl(this.Controls, ctl => ctl.Text == "Some text");
1 голос
/ 29 апреля 2010
void iterateControls(Control ctrl)
{
    foreach(Control c in ctrl.Controls)
    {
        iterateControls(c);
    }
}
0 голосов
/ 16 февраля 2013

Я ненавижу рекурсию, поэтому всегда использую стек для такого рода вещей. Это назначает общий обработчик события для события CheckedChanged каждого элемента управления RadioButton в текущей иерархии элементов управления:

Stack<Control> controlStack = new Stack<Control>();
foreach (Control c in this.Controls)
{
    controlStack.Push(c);
}
Control ctl;
while (controlStack.Count > 0 && (ctl = controlStack.Pop()) != null)
{
    if (ctl is RadioButton)
    {
        (ctl as RadioButton).CheckedChanged += new EventHandler(rb_CheckedChanged);
    }
    foreach (Control child in ctl.Controls)
    {
        controlStack.Push(child);
    }
}

Вы можете легко модифицировать метод расширения Джоша Эйнштейна, чтобы работать таким образом.

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