代码之家  ›  专栏  ›  技术社区  ›  Joan Venge

如何在C中合并多个控件集合?

  •  1
  • Joan Venge  · 技术社区  · 15 年前

    有优雅的方式吗?也许是林肯?

    对于这样的事情:

    List<ControlCollection> list = { ... }
    
    List<Control> merged = list.MergeAll();
    

    编辑:最终的集合将是一维的,从某种意义上说,所有控件都将在那里,而不是以嵌套的方式。

    4 回复  |  直到 15 年前
        1
  •  2
  •   Philip Wallace    15 年前

    这个怎么样?

    public static void Append(this System.Windows.Forms.Control.ControlCollection collection, System.Windows.Forms.Control.ControlCollection newCollection)
    {
        Control[] newControl = new Control[newCollection.Count];
        newCollection.CopyTo(newControl, 0);
        collection.AddRange(newControl);
    }
    

    用途:

        Form form1 = new Form();
        Form form2 = new Form();
        form1.Controls.Append(form2.Controls);
    

    这将使控制树变平:

    public static void FlattenAndAppend(this System.Windows.Forms.Control.ControlCollection collection, System.Windows.Forms.Control.ControlCollection newCollection)
    {
        List<Control> controlList = new List<Control>();
        FlattenControlTree(collection, controlList);
    
        newCollection.AddRange(controlList.ToArray());
    }
    
    public static void FlattenControlTree(System.Windows.Forms.Control.ControlCollection collection, List<Control> controlList)
    {
        foreach (Control control in collection)
        {
            controlList.Add(control);
            FlattenControlTree(control.Controls, controlList);
        }
    }
    
        2
  •  0
  •   Stephen    15 年前

    林克有 Concat Union 方法。是你要找的吗?

        3
  •  0
  •   leppie    15 年前

    树扩展方法

    static class TreeExtensions
    {
      public static IEnumerable<R>TraverseDepthFirst<T, R>(
          this T t,
          Func<T, R> valueselect,
          Func<T, IEnumerable<T>> childselect)
      {
        yield return valueselect(t);
    
        foreach (var i in childselect(t))
        {
          foreach (var item in i.TraverseDepthFirst(valueselect, childselect))
          {
            yield return item;
          }
        }
      }
    }
    

    用途:

    Control c = root_form_or_control;
    
    var allcontrols = c.TraverseDepthFirst(
         x => x, 
         x => x.Controls.OfType<Control>())).ToList();
    
        4
  •  0
  •   Pavel Minaev    15 年前
    var merged = (from cc in list
                  from Control control in cc
                  select cc)
                 .ToList();
    

    或(与显式LINQ方法调用相同):

    var merged = list.SelectMany(cc => cc.Cast<Control>()).ToList();
    

    [编辑] 反映新增加的套料要求:

    static IEnumerable<T> FlattenTree<T>(
        this IEnumerable<T> nodes,
        Func<T, IEnumerable<T>> childrenSelector)
    {
        foreach (T node in nodes)
        {
            yield return node;
            foreach (T child in childrenSelector(node))
            {
                yield return child;
            }
        }
    }
    
    var merged = list.SelectMany(cc => cc.Cast<Control>())
                     .FlattenTree(control => control.Controls.Cast<Control>())
                     .ToList();