如何在C#中合并多个ControlCollections?

时间:2009-11-12 19:22:39

标签: c# .net linq collections

有一种优雅的方式吗?也许和Linq一起?

对于这样的事情:

List<ControlCollection> list = { ... }

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

编辑:最终的集合将是单维的,因为所有控件都在那里,而不是以嵌套的方式。

4 个答案:

答案 0 :(得分:2)

这个怎么样:

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

答案 1 :(得分:0)

Linq拥有ConcatUnion方法。那是你要找的那个吗?

答案 2 :(得分:0)

树扩展方法

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

答案 3 :(得分:0)

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