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

Posted

技术标签:

【中文标题】如何从包含任何容器中的控件的表单中获取所有控件?【英文标题】:How can I get all controls from a Form Including controls in any container? 【发布时间】:2010-12-06 04:47:36 【问题描述】:

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

【问题讨论】:

【参考方案1】:

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

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

然后是这样的:

ApplyAll(this, c => c.Validate());

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

【讨论】:

并没有真正回答标题问题——如何获取所有控件——而不是编辑它们的属性。 @n00dles 引用问题:“例如,我需要禁用表单中的所有按钮” 写完评论后,我想……也许是需要编辑的标题。我有点恼火,因为我正在寻找标题问题的答案。虽然完成了它。 (从一个 Marc 到另一个!)【参考方案2】:

也试试:

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

    

【讨论】:

【参考方案3】:

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

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

【讨论】:

【参考方案4】:

我一直在寻找基于类型启用/禁用控件的解决方案,因此我想出了类似于 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);

【讨论】:

以上是关于如何从包含任何容器中的控件的表单中获取所有控件?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 ViewModel 一次清除 WPF 中的所有控件?

如何根据在表单上的组合框控件中输入的内容从查询中选择所有记录

除了按钮之外,如何禁用表单上的所有控件?

如何在标签中使用表格控件名称-角反应形式

如何使用 vb.net 从 MS Access DB 表单中找出 Activex 控件

如何从表单组中禁用的表单控件中获取值?