Controls
property only gives the immediate children, so it must be called recursively in order to retrieve all the controls. This started me thinking. Wouldn't it be easier to have a function that could flatten out any hierarchy so it could be easily enumerated?At first I thought I'd just used
IEnumerable.SelectMany
, but again I fell foul of the deferred execution. Also some nasty jiggery-pokery would have been necessary to ensure I just didn't end up enumerating only the controls at the bottom of the hierarchy.My solution is this simple method:
IEnumerable<T> Flatten<T>(T parent, Func<T, IEnumerable<T>> childFunction)
{
yield return parent;
foreach (T t in childFunction(parent))
{
foreach (T u in Flatten(t, childFunction))
{
yield return u;
}
}
}
To call this method so it pops up a message box containing the names of all the controls on a form (including the form itself) add a method to the form similar to this:
private void button1_Click(object sender, EventArgs e)
{
var controls = Flatten<Control>(this, c => c.Controls.Cast<Control>());
var builder = new StringBuilder();
controls.ForEach(c => builder.AppendLine(c.Name));
MessageBox.Show(builder.ToString());
}
For an explanation of the
ForEach
method see my previous post.
No comments:
Post a Comment