C# 如何从表单中获取所有控件,包括任何容器中的控件?

C# 如何从表单中获取所有控件,包括任何容器中的控件?,c#,forms,controls,containers,C#,Forms,Controls,Containers,例如,我需要一种禁用表单中所有按钮或验证所有文本框数据的方法。有什么想法吗?提前谢谢 最简单的选择可能是级联: public static void SetEnabled(Control control, bool enabled) { control.Enabled = enabled; foreach(Control child in control.Controls) { SetEnabled(child, enabled); } } 或类似的;当

例如,我需要一种禁用表单中所有按钮或验证所有文本框数据的方法。有什么想法吗?提前谢谢

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

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<Control> action) {
    action(control);
    foreach(Control child in control.Controls) {
        ApplyAll(child, action);
    }
}
还可以尝试:

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

    }
public List getControls(字符串what,控件where)
{
列表控件=新列表();
foreach(其中的控件c.Controls)
{
if(c.GetType().Name==什么)
{
添加(c);
}
否则如果(c.Controls.Count>0)
{
AddRange(getControls(what,c));
}
}
返回控制;
}
私有void Form1\u加载(对象发送方、事件参数e)
{
var c=getControls(“按钮”,该按钮);
}
我更喜欢使用惰性(迭代器)方法来解决问题,因此我使用以下方法:

/// <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;
    }
  }
}
///返回控件层次结构中的所有子级。
///当一个或多个必需参数为null时引发。
///用作层次结构根的控件。
///(可选)要迭代的最大级别数。零就是零
///控件,1将只是控件的子级,2将包括
///孩子们。
/// 
///一个枚举数,它允许使用foreach来处理和迭代此进程中的所有子进程
///等级制度。
/// 
公共静态IEnumerable IterateAllChildren(此控件,
int maxDepth=int.MaxValue)
{
if(control==null)
抛出新的异常(“控制”);
如果(maxDepth==0)
返回新控件[0];
返回IterateAllChildrenSafe(控件,1,maxDepth);
}
私有静态IEnumerable IterateAllChildrenSafe(控件根控件,
整数深度,
整数(最大深度)
{
foreach(rootControl.Controls中的控件)
{
收益率控制;
//只有当我们不是太深并且
//真的有孩子吗
如果(深度>=maxDepth | | control.Controls.Count==0)
继续;
var childrensafe=IterateAllChildrenSafe(控件,深度+1,最大深度);
foreach(子控件中的控件子控件)
{
收益子控制;
}
}
}

我一直在寻找基于类型启用/禁用控件的解决方案,因此我提出了类似于Luiscencio的方法(您也可以修改它以获取所有控件或更改其他属性)

publicstaticvoidsetenabled(ControlCollection-cntrList,bool-enabled,List-typeList=null)
{
foreach(cntrList中的控制cntr)
{
如果(cntr.Controls.Count==0)
如果(类型列表!=null)
{
if(typeList.Contains(cntr.GetType()))
cntr.Enabled=已启用;
}
其他的
cntr.Enabled=已启用;
其他的
setEnabled(cntr.Controls,enabled,typeList);
}
}
公共void loadFormEvents()
{
列表=新列表();
列表。添加(文本框的类型);
setEnabled(frm.Controls,false,list);
}

并没有真正回答标题问题-如何获取所有控件-而不是编辑它们的属性。@n00dle引用问题:“例如,我需要禁用表单中的所有按钮”,在我写下注释后,我想。。。也许是标题需要编辑。我有点恼火,因为我正在寻找标题问题的答案。不过还是做了。(从一个Marc到另一个!)
/// <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;
    }
  }
}
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);
}