Welcome to AspAdvice Sign in | Join | Help

Orcs Goblins and .NET

I enjoy reading and writing. I hope you enjoy at least the former. I have moved my blog to Brendan.Enrick.com.

Syndication

Tags

News

Locations of visitors to this page

Navigation

Archives

Advice Sites

Articles

Blogs

Music

Creating a Recursive FindControl Extension Method

So one of the most useful methods for ASP.NET development that never seems to be included in ASP.NET is a recursive find control method. This problem results from the standard FindControl method on controls only searching within that control. It only finds child controls not grandchildren or anything farther down the line. This means that anything nested within other controls is a pain to access.

This limitation of the standard FindControl is annoying and has prompted me as well as many other people to use homegrown FindControl methods to solve this problem. This is a big problem when trying to programmatically access controls within templates. So earlier today I read on a list someone having trouble with the built-in find control, and it made me thing that a recursive find control would make a great extension method since it is a method plenty of people want to see on the control class anyway. So I went and wrote this simple little extension method.

For this nifty example I'll use this as my Page class. I've nested some Panels here to make sure that a standard find control would not work.

<form id="form1" runat="server">
<div>
    <asp:Panel ID="Panel1" runat="server">
        <asp:Panel ID="Panel2" runat="server">
            <asp:Panel ID="Panel3" runat="server">
                <asp:Panel ID="Panel4" runat="server">
                    <asp:Panel ID="Panel5" runat="server">
                        <asp:Label ID="ControlToFind" runat="server" />
                    </asp:Panel>
                </asp:Panel>
            </asp:Panel>
        </asp:Panel>
    </asp:Panel>
</div>
</form>

Now you'll see here in the code behind I am calling my recursive find control extension method. Notice that I am checking for null afterwards. This is because if I do not find the control my method returns null, so I should check for this. Also because I am using the as statement if the control is not a label my variable will also be null.

protected void Page_Load(object sender, EventArgs e)
{
    Label theLabel = form1.FindControlR("ControlToFind") as Label;
    if (theLabel != null)
    {
        theLabel.Text = "Found it!";
    }
}

Here is the code which makes this cool extension method possible.

public static class Extensions
{
    /// <summary>
    /// Searches recursively in this control to find a control with the name specified.
    /// </summary>
    /// <param name="root">The Control in which to begin searching.</param>
    /// <param name="id">The ID of the control to be found.</param>
    /// <returns>The control if it is found or null if it is not.</returns>
    public static Control FindControlR(this Control root, string id)
    {
        System.Web.UI.Control controlFound; 
        if (root != null) 
        { 
            controlFound = root.FindControl(id);
            if (controlFound != null)
            {
                return controlFound;
            }
            foreach (Control c in root.Controls) 
            {
                controlFound = c.FindControlR(id);
                if (controlFound != null)
                {
                    return controlFound;
                }
            } 
        } 
        return null;
    }
}

To create an extension method all I need to do is create a static method in a static class and pass as a parameter "this Type name" where Type and name are the type we wish to extend and name is a local variable name for the instance with which we wish to interact.

One thing I don't see in many examples of extension methods which I have used here is passing a parameter in the extension method. It really is this simple to pass the extra parameter.

This syntax reminds me a lot of the python language whose non-static class methods accept "this" as a parameter. It defines them as taking the instance as a parameter.

Have a great day!

Published Monday, March 31, 2008 11:29 AM by Brendan

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# Creating a Recursive FindControl Extension Method @ Wednesday, June 18, 2008 9:27 AM

You've been kicked (a good thing) - Trackback from DotNetKicks.com

DotNetKicks.com

# Recursive FindControl @ Monday, September 22, 2008 10:17 AM

I&#39;ve been asking for a recursive FindControl() method as a method off of System.Web.UI.Control for

Community Blogs

# re: Creating a Recursive FindControl Extension Method @ Wednesday, December 10, 2008 11:55 PM

You've been knacked. Keep up the good work.

eKnacks

# re: Creating a Recursive FindControl Extension Method @ Wednesday, April 01, 2009 1:03 PM

Thanks for posting this! Solved a really complex nesting problem for me on a page full on AJAX with content panels, tabs etc. etc. I didn't know where to start when FindControl didn't work. Much appreciated. Barry

Barry Clark

# re: Creating a Recursive FindControl Extension Method @ Sunday, August 09, 2009 2:07 PM

Thank you and Thank you again. I agree with Barry Clark. you not only saved my bacon from the fire, you saved the whole breaskfast.

newbie hd

# re: Creating a Recursive FindControl Extension Method @ Tuesday, August 18, 2009 5:10 PM

I stuggled with this for almost 6 hours today. Your solution took 5 minutes to implement and works perfectly. Thank you VERY MUCH!!!

thanks

# re: Creating a Recursive FindControl Extension Method @ Wednesday, December 23, 2009 12:50 PM

I have been struggling with this for days.... 5 minutes with this and my problems are solved... Thank you....

Dave B

# re: Creating a Recursive FindControl Extension Method @ Tuesday, March 09, 2010 11:37 AM

I couldn't get it to work - if I ran the code as posted it fell over on the line:

controlFound = c.FindControlR(id);

Error was something like 'c does not contain a definition for FindControR'

I changed it to:

controlFound = FindControlR(c, id);

and it worked. So, what am I missing? I presume it works for other people? FindControlR is expecting a Control and a string - how would it work when saying c.FindControlR(id) - i.e. just passing a string to something which does not have a method called FindControlR?

Mike Wilson

# re: Creating a Recursive FindControl Extension Method @ Tuesday, March 09, 2010 3:52 PM

Mike,

Two things you might want to check here. Make sure that you have a using statement at the top of your file including the namespace where the extension method is located. Without that using statement you don't have access to the method.

You might also make sure that in your method declaration that you have "this" before the Control parameter.

public static Control FindControlR(this Control root, string id)

If that doesn't resolve the issue for you, just use the contact form on the blog and I'll email with you and we'll figure out why it isn't working.

Brendan

# Generic Recursive Find Control Extension @ Monday, July 26, 2010 3:32 PM

Generic Recursive Find Control Extension

Brendan Enrick

# Generic Recursive Find Control Extension @ Friday, July 30, 2010 9:45 AM

Generic Recursive Find Control Extension

Brendan Enrick

# re: Creating a Recursive FindControl Extension Method @ Saturday, September 17, 2011 8:25 PM

I have copied the code exactly as seen, into a class file called Extensions.cs in the App_Code of my application.  I get a clean compile but when I execute the application, immediately upon execution of it (just displaying the home page) I get a server error and the error is:  CS0121: The call is ambiguous between the following methods or properties: 'Ulc.LoanRecon.Ui.Extensions.FindControlR(System.Web.UI.Control, string)' and 'Ulc.LoanRecon.Ui.Extensions.FindControlR(System.Web.UI.Control, string)'

Any ideas?

Warren

# re: Creating a Recursive FindControl Extension Method @ Friday, September 30, 2011 12:44 AM

Nice post! My own FindControlRecursive helped me out many times. Especially, when I deal with MasterPages. 

Thank you!

dotNetFollower

Leave a Comment

(required) 
required 
(required) 
Enter the code you see below