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