Получить все элементы управления определенного типа - PullRequest
38 голосов
/ 08 января 2011

У меня есть несколько коробок с картинками, и мне нужно загружать в них случайные изображения во время выполнения.Поэтому я подумал, что было бы неплохо иметь коллекцию всех коробок с картинками, а затем назначать им изображения с помощью простого цикла.Но как мне это сделать?Или, может быть, есть какие-то другие лучшие решения этой проблемы?

Ответы [ 9 ]

74 голосов
/ 08 января 2011

Использование битов LINQ:

foreach(var pb in this.Controls.OfType<PictureBox>())
{
  //do stuff
}

Однако это будет заботиться только о PictureBoxes в главном контейнере.

25 голосов
/ 08 января 2011

Вы можете использовать этот метод:

public static IEnumerable<T> GetControlsOfType<T>(Control root)
    where T : Control
{
    var t = root as T;
    if (t != null)
        yield return t;

    var container = root as ContainerControl;
    if (container != null)
        foreach (Control c in container.Controls)
            foreach (var i in GetControlsOfType<T>(c))
                yield return i;
}

Тогда вы могли бы сделать что-то вроде этого:

foreach (var pictureBox in GetControlsOfType<PictureBox>(theForm)) {
    // ...
}
7 голосов
/ 08 января 2011

Если вы хотя бы в .NET 3.5, значит, у вас есть LINQ, а это значит, что, поскольку ControlCollection реализует IEnumerable, вы можете просто сделать:

var pictureBoxes = Controls.OfType<PictureBox>();
3 голосов
/ 22 апреля 2014

Я использую этот универсальный рекурсивный метод:

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

public static IList<T> GetAllControlsRecusrvive<T>(Control control) where T :Control 
{
    var rtn = new List<T>();
    foreach (Control item in control.Controls)
    {
        var ctr = item as T;
        if (ctr!=null)
        {
            rtn.Add(ctr);
        }
        else
        {
            rtn.AddRange(GetAllControlsRecusrvive<T>(item));
        }

    }
    return rtn;
}
2 голосов
/ 23 марта 2018

Простая функция, простая для понимания, рекурсивная, и она работает, вызывая ее внутри любого элемента управления формы:

private void findControlsOfType(Type type, Control.ControlCollection formControls, ref List<Control> controls)
    {
        foreach (Control control in formControls)
        {
            if (control.GetType() == type)
                controls.Add(control);
            if (control.Controls.Count > 0)
                findControlsOfType(type, control.Controls, ref controls);
        }
    }

Вы можете назвать это несколькими способами. Чтобы получить кнопки:

List<Control> buttons = new List<Control>();
findControlsOfType(typeof(Button), this.Controls, ref buttons);

Чтобы получить панели:

List<Control> panels = new List<Control>();
findControlsOfType(typeof(Panel), this.Controls, ref panels);

и т.д.

2 голосов
/ 12 мая 2017

Вот еще одна версия, так как существующие предоставленные не совсем то, что я имел в виду.Опционально этот метод работает как метод расширения и исключает проверку типа корневого / родительского контейнера.Этот метод в основном является методом «Получить все дочерние элементы управления типа T»:

public static System.Collections.Generic.IEnumerable<T> ControlsOfType<T>(this System.Web.UI.Control control) where T: System.Web.UI.Control{
    foreach(System.Web.UI.Control childControl in control.Controls){
        if(childControl is T) yield return (T)childControl;
        foreach(var furtherDescendantControl in childControl.ControlsOfType<T>()) yield return furtherDescendantControl;
    }
}
2 голосов
/ 24 августа 2015
    public static List<T> FindControlByType<T>(Control mainControl,bool getAllChild = false) where T :Control
    {
        List<T> lt = new List<T>();
        for (int i = 0; i < mainControl.Controls.Count; i++)
        {
            if (mainControl.Controls[i] is T) lt.Add((T)mainControl.Controls[i]);
            if (getAllChild) lt.AddRange(FindControlByType<T>(mainControl.Controls[i], getAllChild));
        }
        return lt;
    }
0 голосов
/ 03 ноября 2018

Принимает контроль в качестве контейнера:

        private static IEnumerable<T> GetControlsOfType<T>(this Control root)
        where T : Control
    {
        if (root is T t)
            yield return t;

        if (root is ContainerControl || root is Control)
        {
            var container = root as Control;
            foreach (Control c in container.Controls)
                foreach (var i in GetControlsOfType<T>(c))
                    yield return i;
        }
    }
0 голосов
/ 05 апреля 2018

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

    foreach (Control c in panel.Controls)
    {
        if (c.GetType().Name == "TextBox")
        {
            c.Text = "";
        }
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...