LINQ - The Uber FindControl

With a simple extension method to ControlCollection to flatten the control tree you can use LINQ to query the control tree:

public static class PageExtensions
{
    public static IEnumerable<Control> All(this ControlCollection controls)
    {
        foreach (Control control in controls)
        {
            foreach (Control grandChild in control.Controls.All())
                yield return grandChild;

            yield return control;
        }
    }
}
Now I can do things like this:
// get the first empty textbox
TextBox firstEmpty = accountDetails.Controls
    .All()
    .OfType<TextBox>()
    .Where(tb => tb.Text.Trim().Length == 0)
    .FirstOrDefault();

// and focus it
if (firstEmpty != null)
    firstEmpty.Focus();

Pretty cool! I can do all sorts of querying of the control tree now. LINQ you are my hero.

Published Friday, June 29, 2007 9:14 AM by findleyd

Comments

# re: LINQ - The Uber FindControl

Tuesday, July 3, 2007 11:23 PM by ChrisKo

Hmmmm here at home with Firefox, it seems to have a nice scrollable DIV, guess it was IE6 at work.

# re: LINQ - The Uber FindControl

Wednesday, September 26, 2007 6:51 AM by Aykut Sevim

How can we activate this extension method? I think there already exist an All() method in Page class and I cannot make use of your method.

# re: LINQ - The Uber FindControl

Saturday, September 29, 2007 8:45 AM by findleyd

If you put the PageExtensions class inside a namespace you'll need to make sure you have a using for that namespace. This adds the All method to the Controls collection and not the Page class so you should be ok.

# re: LINQ - The Uber FindControl

Wednesday, April 29, 2009 5:02 PM by rouftop

Really handy.  Will perf come to bite me in the butt though?

# re: LINQ - The Uber FindControl

Monday, May 25, 2009 5:56 AM by John Chavez

Still cannot get it to work getting this error:

CS1501: No overload for method 'All' takes '0' arguments

Using this code:

Page.Controls.All().OfType<WebControl>().ToList().ForEach(c => c.Enabled = (CardID != 0));

# re: LINQ - The Uber FindControl

Monday, May 25, 2009 11:00 AM by findleyd

Just make sure that whatever namespace PageExtensions is in is in scope. You may need to add a using to your code behind.

# re: LINQ - The Uber FindControl

Tuesday, June 9, 2009 11:06 AM by Marco

Man, I've just thrown away my code... poor.

# re: LINQ - The Uber FindControl

Tuesday, September 15, 2009 4:54 PM by Anderson Imes

I found this useful for about the 10th time today and decided it was time to leave a comment about it.  Thanks for writing this.

# re: LINQ - The Uber FindControl

Sunday, January 10, 2010 4:59 PM by jsd

Linq is magic, powerful, love to use it in my aspnet app. THANKS.

# re: LINQ - The Uber FindControl

Monday, May 17, 2010 10:31 AM by reece

Forgive me, I am very new to LINQ, and I am trying to do this in VB.NET, and I know yield isn't supported. Do you have an example for us VB people?

Thank you for your time.

# re: LINQ - The Uber FindControl

Tuesday, July 27, 2010 11:35 PM by butterfly

where to place PageExtensions Or Could u like to give me complete code thanks in advanced

# re: LINQ - The Uber FindControl

Wednesday, July 28, 2010 10:03 AM by findleyd

Just make sure you put the PageExtensions class in a namespace and put a using statement at the top of your code behind cs.

# re: LINQ - The Uber FindControl

Thursday, September 30, 2010 11:22 PM by chad

Question... Is this better than just using the IEnumerable.Cast<> extension method to get an IEnumerable<Control> to query?  It's already there and does the work for you.

Like this:

// get the first empty textbox

var firstEmpty = Controls

   .Cast<Control>()

   .OfType<TextBox>()

   .Where(tb => tb.Text.Trim().Length == 0)

   .FirstOrDefault();

// and focus it

if (firstEmpty != null)

   firstEmpty.Focus();

# re: LINQ - The Uber FindControl

Friday, October 1, 2010 7:35 AM by findleyd

Actually .All does more than .Cast. .All is used to recurse all the controls in the tree. Then .OfType<T> does a filter and a cast.

# re: LINQ - The Uber FindControl

Friday, October 1, 2010 9:11 AM by chad

I actually realized after the fact that I can just do IEnumerable.OfType<> without the cast... never noticed that til you mentioned that the cast is there w/ the filter.  So what's the advantage of recursing the tree? Sorry if my question seems, I don't know, rude or something, I'm honestly wondering.

# re: LINQ - The Uber FindControl

Friday, October 1, 2010 11:10 AM by findleyd

Sometimes the control(s) you are looking for can be buried inside other controls like a Panel, FormView, GridView, Login etc. I actually used .All in one of my projects to get to the edit boxes in a Login control.

# re: LINQ - The Uber FindControl

Sunday, October 3, 2010 8:54 PM by chad

ah, good point! very cool... sorry I didn't see it earlier. =)

# re: LINQ - The Uber FindControl

Tuesday, June 28, 2011 8:14 AM by weblogs.asp.net

Linq the uber findcontrol.. Bang-up :)

# re: LINQ - The Uber FindControl

Monday, September 24, 2012 11:57 AM by Carlos Ponce

Just wanted to say thanks for this very useful extension