有一种优雅的方式吗?也许和Linq一起?
对于这样的事情:
List<ControlCollection> list = { ... }
List<Control> merged = list.MergeAll();
编辑:最终的集合将是单维的,因为所有控件都在那里,而不是以嵌套的方式。
答案 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拥有Concat
和Union
方法。那是你要找的那个吗?
答案 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();