Recursive control search with LINQ Recursive control search with LINQ asp.net asp.net

Recursive control search with LINQ


Take the type/ID checking out of the recursion, so just have a "give me all the controls, recursively" method, e.g.

public static IEnumerable<Control> GetAllControls(this Control parent){    foreach (Control control in parent.Controls)    {        yield return control;        foreach(Control descendant in control.GetAllControls())        {            yield return descendant;        }    }}

That's somewhat inefficient (in terms of creating lots of iterators) but I doubt that you'll have a very deep tree.

You can then write your original query as:

var checkBoxes = this.GetAllControls()                     .OfType<CheckBox>()                     .TakeWhile<CheckBox>(cb => cb.Checked);

(EDIT: Changed AllControls to GetAllControls and use it properly as a method.)


public static IEnumerable<Control> AllControls(this Control container){    //Get all controls    var controls = container.Controls.Cast<Control>();    //Get all children    var children = controls.Select(c => c.AllControls());    //combine controls and children    var firstGen = controls.Concat(children.SelectMany(b => b));    return firstGen;}

Now based on the above function, we can do something like this:

public static Control FindControl(this Control container, string Id){    var child = container.AllControls().FirstOrDefault(c => c.ID == Id);    return child;}


My suggestion to make the AllControls recursive is:

    public static IEnumerable<Control> AllControls(this Control parent)    {        foreach (Control control in parent.Controls)        {             yield return control;        }        foreach (Control control in parent.Controls)        {            foreach (Control cc in AllControls(control)) yield return cc;        }    }

The second foreach looks weird, but this is the only way I know to "flatten" the recursive call.