Reputation: 331330
Is there an elegant way of doing this? Perhaps with Linq?
For something like this:
List<ControlCollection> list = { ... }
List<Control> merged = list.MergeAll();
EDIT: The final collection will be single dimensional in a sense that all controls will be there, not in a nested way.
Upvotes: 1
Views: 2300
Reputation: 101615
var merged = (from cc in list
from Control control in cc
select cc)
.ToList();
or (same thing with explicit LINQ method calls):
var merged = list.SelectMany(cc => cc.Cast<Control>()).ToList();
[EDIT] Reflecting the newly added nesting requirement:
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();
Upvotes: 0
Reputation: 117300
Tree extension method
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;
}
}
}
}
Usage:
Control c = root_form_or_control;
var allcontrols = c.TraverseDepthFirst(
x => x,
x => x.Controls.OfType<Control>())).ToList();
Upvotes: 0
Reputation: 8025
How about this:
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);
}
Usage:
Form form1 = new Form();
Form form2 = new Form();
form1.Controls.Append(form2.Controls);
This will flatten the control tree:
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);
}
}
Upvotes: 2
Reputation: 3621
Linq has Concat
and Union
methods. Is one of those what you're looking for?
Upvotes: 0