Подтвердить что ты не робот

Получить все элементы управления определенного типа

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

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)) {
    // ...
}

Ответ 3

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

var pictureBoxes = Controls.OfType<PictureBox>();

Ответ 4

Здесь другая версия, поскольку существующие предоставленные были не совсем тем, что я имел в виду. Этот метод, возможно, работает как метод расширения и исключает проверку типа корневого/родительского контейнера. Этот метод в основном представляет собой метод Get all descendent controls типа 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;
    }
}

Ответ 5

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

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

и т.п.

Ответ 6

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

Предположение об этом методе состоит в том, что если элемент управления 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;
}

Ответ 7

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

Ответ 8

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

    foreach (Control c in panel.Controls)
    {
        if (c.GetType().Name == "TextBox")
        {
            c.Text = "";
        }
    }