Как объединить несколько ControlCollections в C #? - PullRequest
1 голос
/ 12 ноября 2009

Есть ли элегантный способ сделать это? Возможно с Linq?

Примерно так:

List<ControlCollection> list = { ... }

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

РЕДАКТИРОВАТЬ: окончательная коллекция будет одномерной в том смысле, что все элементы управления будут там, а не вложенным способом.

Ответы [ 4 ]

2 голосов
/ 12 ноября 2009

Как насчет этого:

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);
    }
}
0 голосов
/ 12 ноября 2009
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();
0 голосов
/ 12 ноября 2009

Метод расширения дерева

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();
0 голосов
/ 12 ноября 2009

Linq имеет Concat и Union методы. Является ли один из тех, что вы ищете?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...