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

Lui*_*cio 5 c# forms controls containers

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

Mar*_*ell 22

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

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

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

public static void ApplyAll(Control control, Action<Control> action) {
    action(control);
    foreach(Control child in control.Controls) {
        ApplyAll(child, action);
    }
}
Run Code Online (Sandbox Code Playgroud)

那么像:

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

ApplyAll(this, c => {c.Enabled = false; });
Run Code Online (Sandbox Code Playgroud)


Fri*_*Guy 5

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

/// <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;
    }
  }
}
Run Code Online (Sandbox Code Playgroud)