如何从包含任何容器中的控件的表单中获取所有控件?

例如,我需要一种方法来禁用表单中的所有按钮或validation所有文本框的数据。 有任何想法吗? 提前致谢!

最简单的选择可能是级联:

public static void SetEnabled(Control control, bool enabled) { control.Enabled = enabled; foreach(Control child in control.Controls) { SetEnabled(child, enabled); } } 

或类似的; 你当然可以传递一个委托使其相当通用:

 public static void ApplyAll(Control control, Action action) { action(control); foreach(Control child in control.Controls) { ApplyAll(child, action); } } 

那么像:

 ApplyAll(this, c => c.Validate()); ApplyAll(this, c => {c.Enabled = false; }); 

我更喜欢使用懒惰(迭代器)方法解决问题,所以这就是我使用的方法:

 ///  Return all of the children in the hierarchy of the control.  ///  Thrown when one or more required arguments are null.  ///  The control that serves as the root of the hierarchy.  ///  (optional) The maximum number of levels to iterate. Zero would be no /// controls, 1 would be just the children of the control, 2 would include the children of the /// children.  ///  /// An enumerator that allows foreach to be used to process iterate all children in this /// hierarchy. ///  public static IEnumerable IterateAllChildren(this Control control, int maxDepth = int.MaxValue) { if (control == null) throw new ArgumentNullException("control"); if (maxDepth == 0) return new Control[0]; return IterateAllChildrenSafe(control, 1, maxDepth); } private static IEnumerable IterateAllChildrenSafe(Control rootControl, int depth, int maxDepth) { foreach (Control control in rootControl.Controls) { yield return control; // only iterate children if we're not too far deep and if we // actually have children if (depth >= maxDepth || control.Controls.Count == 0) continue; var children = IterateAllChildrenSafe(control, depth + 1, maxDepth); foreach (Control subChildControl in children) { yield return subChildControl; } } } 

还试试:

 public List getControls(string what, Control where) { List controles = new List(); foreach (Control c in where.Controls) { if (c.GetType().Name == what) { controles.Add(c); } else if (c.Controls.Count > 0) { controles.AddRange(getControls(what, c)); } } return controles; } private void Form1_Load(object sender, EventArgs e) { var c = getControls("Button", this); } 

我一直在寻找相同的解决方案来启用/禁用基于类型的控件,所以我想出了类似于Luiscencio方法(你也可以修改它以获得所有控件或更改其他属性)。

 public static void setEnabled (ControlCollection cntrList ,bool enabled,List typeList = null) { foreach (Control cntr in cntrList) { if (cntr.Controls.Count == 0) if (typeList != null) { if (typeList.Contains(cntr.GetType())) cntr.Enabled = enabled; } else cntr.Enabled = enabled; else setEnabled(cntr.Controls, enabled, typeList); } } public void loadFormEvents() { List list = new List (); list.Add(typeof(TextBox)); setEnabled(frm.Controls ,false,list); }