У меня есть несколько графических ящиков, и мне нужно загружать в них случайные изображения во время выполнения. Поэтому я подумал, что было бы неплохо иметь коллекцию всех графических ящиков, а затем назначать изображения им с помощью простого цикла. Но как мне это сделать? Или, может быть, есть ли другие более эффективные решения этой проблемы?
Получить все элементы управления определенного типа
Ответ 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 = "";
}
}