我有多个图片框,需要在运行时随机加载图像。因此,我认为拥有所有图片框的集合,然后使用简单循环为它们分配图像会很不错。但是我该如何做呢?或者说是否有更好的解决方案?
使用 LINQ:
foreach(var pb in this.Controls.OfType<PictureBox>())
{
//do stuff
}
然而,这只会处理主容器中的PictureBox。
您可以使用此方法:
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)) {
// ...
}
root.Controls.OfType<T>
更啰嗦。 - Dan TaoOfType<T>()
)。 - cdhowie如果您的 .NET 版本至少为 3.5,则可以使用 LINQ。由于 ControlCollection
实现了 IEnumerable
,因此您只需执行以下操作:
var pictureBoxes = Controls.OfType<PictureBox>();
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);
etc.
我使用这个通用的递归方法:
这种方法的假设是,如果控件是 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;
}
由于现有提供的版本并不完全符合我的想法,这里提供另一种版本。这个版本可以作为一个扩展方法,可选地排除检查根/父容器的类型。该方法基本上是一个“获取所有类型为 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;
}
}
对我来说,这是最简单的。在我的应用程序中,我试图清除面板中的所有文本框:
foreach (Control c in panel.Controls)
{
if (c.GetType().Name == "TextBox")
{
c.Text = "";
}
}
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;
}
考虑容器控制:
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;
}
}