如何在C#中合并多个ControlCollection?
有没有一种优雅的方法?也许是和林克 对于这样的事情:如何在C#中合并多个ControlCollection?,c#,.net,linq,collections,C#,.net,Linq,Collections,有没有一种优雅的方法?也许是和林克 对于这样的事情: List<ControlCollection> list = { ... } List<Control> merged = list.MergeAll(); List List={…} List merged=List.MergeAll(); 编辑:从某种意义上说,最终的集合将是一维的,所有控件都将在那里,而不是以嵌套的方式。Linq有Concat和Union方法。你要找的就是这些吗?这个怎么样: public
List<ControlCollection> list = { ... }
List<Control> merged = list.MergeAll();
List List={…}
List merged=List.MergeAll();
编辑:从某种意义上说,最终的集合将是一维的,所有控件都将在那里,而不是以嵌套的方式。Linq有
Concat
和Union
方法。你要找的就是这些吗?这个怎么样:
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);
Control c = root_form_or_control;
var allcontrols = c.TraverseDepthFirst(
x => x,
x => x.Controls.OfType<Control>())).ToList();
这将展平控制树:
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);
}
}
public static void flatten和append(this System.Windows.Forms.Control.ControlCollection集合,System.Windows.Forms.Control.ControlCollection新集合)
{
列表控制器=新列表();
FlattControlTree(集合、控制器);
newCollection.AddRange(controlList.ToArray());
}
公共静态控件树(System.Windows.Forms.Control.ControlCollection集合,列表控件列表)
{
foreach(集合中的控件)
{
controlList.Add(控制);
FlattControlTree(control.Controls,controlList);
}
}
树扩展方法
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;
}
}
}
}
静态类树扩展
{
公共静态IEnumerableTraverseDepthFirst(
这个T T,,
Func valueselect,
Func(儿童选择)
{
收益率返回值选择(t);
foreach(childselect(t)中的变量i)
{
foreach(i.TraverseDepthFirst(valueselect,childselect)中的var项)
{
收益回报项目;
}
}
}
}
用法:
Form form1 = new Form();
Form form2 = new Form();
form1.Controls.Append(form2.Controls);
Control c = root_form_or_control;
var allcontrols = c.TraverseDepthFirst(
x => x,
x => x.Controls.OfType<Control>())).ToList();
Control c=根形式或控件;
var allcontrols=c.TraverseDepthFirst(
x=>x,
x=>x.Controls.OfType()).ToList();
或者(与显式LINQ方法调用相同):
var merged=list.SelectMany(cc=>cc.Cast()).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();
静态IEnumerable树(
这是一个可数节点,
Func儿童选择器)
{
foreach(节点中的T节点)
{
收益回报节点;
foreach(childrenSelector(节点)中的T child)
{
退换子女;
}
}
}
var merged=list.SelectMany(cc=>cc.Cast())
.flattree(control=>control.Controls.Cast())
.ToList();
非常感谢,但他们仍然需要我为每个元素对其进行循环。我想用一个电话什么的。你为什么需要一个循环?您只需对结果使用ToList()
即可获得列表
。谢谢,我实际上忘记了一些事情。它是否处理控件中的控件,从而摆脱所有嵌套级别?是的。当一个控件移动时,它的所有子控件都会移动。不,我的意思是,它是否会添加它们以使列表不是多维的。为什么要使用Array.CreateInstance?编写新控件[newCollection.Count]
不是更容易吗?谢谢,我的代码也做了类似的事情,所以我想这是唯一的方法。