C# 如何从包含任何容器中的控件的表单中获取所有控件?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1558127/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I get all controls from a Form Including controls in any container?
提问by Luiscencio
I need, for example, a way to disable all buttons in a form or validate all textboxes' data. Any ideas? Thanks in advance!
例如,我需要一种方法来禁用表单中的所有按钮或验证所有文本框的数据。有任何想法吗?提前致谢!
采纳答案by Marc Gravell
The simplest option may be to cascade:
最简单的选择可能是级联:
public static void SetEnabled(Control control, bool enabled) {
control.Enabled = enabled;
foreach(Control child in control.Controls) {
SetEnabled(child, enabled);
}
}
or similar; you could of course pass a delegate to make it fairly generic:
或类似的;你当然可以通过一个委托来使它相当通用:
public static void ApplyAll(Control control, Action<Control> action) {
action(control);
foreach(Control child in control.Controls) {
ApplyAll(child, action);
}
}
then things like:
然后是这样的:
ApplyAll(this, c => c.Validate());
ApplyAll(this, c => {c.Enabled = false; });
回答by Luiscencio
Also try:
还可以尝试:
public List<Control> getControls(string what, Control where)
{
List<Control> controles = new List<Control>();
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);
}
回答by FriendlyGuy
I prefer a lazy (iterator) approach to the problem, so this is what I use:
我更喜欢用惰性(迭代器)方法来解决这个问题,所以这就是我使用的:
/// <summary> Return all of the children in the hierarchy of the control. </summary>
/// <exception cref="ArgumentNullException"> Thrown when one or more required arguments are null. </exception>
/// <param name="control"> The control that serves as the root of the hierarchy. </param>
/// <param name="maxDepth"> (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. </param>
/// <returns>
/// An enumerator that allows foreach to be used to process iterate all children in this
/// hierarchy.
/// </returns>
public static IEnumerable<Control> 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<Control> 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;
}
}
}
回答by MoeCaruso
I've been looking for a solution for the same to enable/disable controls based on type,so I came up with this similar to Luiscencio approach (You may also modify it to get all controls or change other properties).
我一直在寻找相同的解决方案来根据类型启用/禁用控件,所以我想出了类似于 Luiscencio 的方法(您也可以修改它以获取所有控件或更改其他属性)。
public static void setEnabled (ControlCollection cntrList ,bool enabled,List<Type> 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<Type> list = new List<Type> ();
list.Add(typeof(TextBox));
setEnabled(frm.Controls ,false,list);
}