【问题标题】:General recursive method for iterate all controls and their related controls in a windows form在窗体中迭代所有控件及其相关控件的通用递归方法
【发布时间】:2013-01-07 04:22:23
【问题描述】:

是否有任何通用递归方法可以在 Windows 窗体中迭代所有控件(包括工具条及其项、绑定导航器及其项...)? (其中一些不是从 Control 类继承的)或至少迭代工具条及其项、绑定导航器及其项?

【问题讨论】:

    标签: c# winforms controls toolstrip


    【解决方案1】:

    您将在这里遇到障碍,因为ToolStrip 使用Items 而不是Controls,并且ToolStripItem 不继承自ControlToolStripItemControl 都继承自 Component,所以充其量你可以得到一个 IEnumerable<Component>

    您可以使用以下扩展方法来完成此操作:

    public static class ComponentExtensions
    {
        public static IEnumerable<Component> GetAllComponents(this Component component)
        {
            IEnumerable<Component> components;
            if (component is ToolStrip) components = ((ToolStrip)component).Items.Cast<Component>();
            else if (component is Control) components = ((Control)component).Controls.Cast<Component>();
            else components = Enumerable.Empty<Component>();    //  figure out what you want to do here
            return components.Concat(components.SelectMany(x => x.GetAllComponents()));
        }
    }
    

    在 Windows 窗体上,您可以在 foreach 循环中处理所有这些组件:

    foreach (Component component in this.GetAllComponents())
    {
        //    Do something with component...
    }
    

    不幸的是,您将进行大量手动类型检查和强制转换。

    【讨论】:

      【解决方案2】:

      在这种情况下我通常会这样做:

      首先定义一个接受 Control 作为参数的委托:

      public delegate void DoSomethingWithControl(Control c);
      

      然后实现一个将此委托作为第一个参数的方法,并将递归执行它的控件作为第二个参数。此方法首先执行委托,然后在控件的 Controls 集合上循环以递归调用自身。这是有效的,因为 Controls 在 Control 中定义,并为简单的控件返回一个空集合,例如:

      public void RecursivelyDoOnControls(DoSomethingWithControl aDel, Control aCtrl)
      {
          aDel(aCtrl);
          foreach (Control c in aCtrl.Controls)
          {
              RecursivelyDoOnControls(aDel, c);
          }
      }
      

      现在您可以将要为每个控件执行的代码放在一个方法中,并通过委托在 Form 上调用它:

      private void DoStg(Control c)
      {
          // whatever you want
      }
      
      RecursivelyDoOnControls(new DoSomethingWithControl(DoStg), yourForm);
      

      编辑:

      由于您也在处理 ToolStripItems,因此您可以定义委托来处理通用对象,然后编写递归方法的不同重载。 IE。像这样:

      public delegate void DoSomethingWithObject(Object o);
      
      public void RecursivelyDo(DoSomethingWithObject aDel, Control aCtrl)
      {
          aDel(aCtrl);
          foreach (Control c in aCtrl.Controls)
          {
              RecursivelyDoOnControls(aDel, c);
          }
      }
      
      public void RecursivelyDo(DoSomethingWithObject aDel, ToolStrip anItem)
      {
          aDel(anItem);
          foreach (ToolstripItem c in anItem.Items)
          {
              RecursivelyDo(aDel, c);
          }
      }
      
      public void RecursivelyDo(DoSomethingWithObject aDel, ToolStripDropDownButton anItem)
      {
          aDel(anItem);
          foreach (ToolStripItem c in anItem.DropDownItems)
          {
              RecursivelyDo(aDel, c);
          }
      }
      
      //and so on
      

      【讨论】:

      • 但是一些对象比如toolstripbuttons是从Control类继承来的。
      猜你喜欢
      • 2013-01-06
      • 2020-06-16
      • 1970-01-01
      • 1970-01-01
      • 2011-02-13
      • 1970-01-01
      • 1970-01-01
      • 2022-11-30
      • 2023-04-10
      相关资源
      最近更新 更多