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

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

【问题讨论】:

    标签: c# forms controls containers


    【解决方案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);
        }
        

        【讨论】:

          猜你喜欢
          • 2011-06-04
          • 2011-03-21
          • 2012-01-25
          • 1970-01-01
          • 2011-04-26
          • 2021-12-23
          • 2012-10-10
          • 1970-01-01
          • 2012-11-29
          相关资源
          最近更新 更多