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.