Page.FindControl() Returning Null Issues and Solutions Within Another Control

Alright, I’m going to have a lot of blog posts over the next few days going over my wonderful expereinces learning how to create advanced server controls, and just how hard it is to find good information on the subject. But the problem I ran into today was having Page.FindControl() not work as expected.

Problem

Page.FindControl() can be misleading. A developer without understanding the situation could assume FindControl() will return a control found within that page. This is completely wrong. The reason this does not work is because Page does not have its own FindControl() function. It actually inherits this from Control, because Page inherits control. So FindControl() is really more like a FindChildrenControls(), and it is not recursive.

Example

I have some code that does a Page.FindControl() for a GridView. However, later I move the GridView into an UpdatePanel to add ajax enabled stuff. All of a sudden my Page.FindControl() doesn’t work. The reason? Because my GridView is no longer a direct child of the Page and it is now a child of the UpdatePanel. So instead of being Page -> GridView it is Page -> UpdatePanel -> GridView.

Solution

I found a blog post for a recursive post. Here is the code:

[csharp]
private Control FindControlRecursive(Control root, string id)
{
if (root.ID == id)
{
return root;
}

foreach (Control c in root.Controls)
{
Control t = FindControlRecursive(c, id);
if (t != null)
{
return t;
}
}

return null;
}
[/csharp]

21 thoughts on “Page.FindControl() Returning Null Issues and Solutions Within Another Control

  1. thx for that post, it was quite helpful and made me understand the innner workings of asp.net a little better 😀

    Like

  2. Thank you sooooooooooooooooo much

    Like

  3. You’re welcome 🙂 I haven’t used ASP.NET for almost a year now, but I’m glad my findings still help people out.

    Like

  4. Thank you. Thank you. Thank you.

    Like

  5. I am kind of a rookie to ASP.Net controls. I created a dynamicPanel Control (custom) for doing partial refreshes with AJAX. I cant find the control on a page using a masterpage and a content panel. What would be the value for the “Control Root”?

    Like

  6. Thank you.

    Like

  7. This is great!

    Like

  8. Thanks so much!

    Like

  9. Thank Heavens! I spent a little bit of time on this and was pulling my hair out. Thanks for saving me potential hours!

    Like

  10. Thank you very much!!! What a life saver.

    Like

  11. Replace Page.FindControl() to NamingContainer.FindControl()

    Like

  12. Thank you very much!!!

    Like

  13. Yes, many thanks !

    Like

  14. Hi Tom. I replaced Page.FindControl() with NamingContainer.FindControl(), but I am getting a
    object Reference not set to an instance of an object error.

    My code is as follows:

    string ctrlStr = String.Empty;
    Control c = null;
    foreach (string ctl in HttpContext.Current.Request.Form)
    {
    // handle ImageButton controls …
    if (ctl.EndsWith(“.x”) || ctl.EndsWith(“.y”))
    {
    ctrlStr = ctl.Substring(0, ctl.Length – 2).Replace(“$”, “_”);
    //c = page.FindControl(ctrlStr);
    c = page.NamingContainer.FindControl(ctrlStr);
    }

    WHEELS

    Like

  15. Hi, i rarely subscribe to all possible web site in the world, but i have donne it with yours just to thanks you.

    I regularly got a lot of problem to correctly findcontrol for a lot of situation of control inside another control, and so on…

    for now it is so easy with the function you write above

    thanks a lot again 🙂

    Like

  16. Hi, thanks!

    Improved it a bit

    private Control FindControlRecursive(string id)
    {
    Page page = HttpContext.Current.Handler as Page;
    return FindControlRecursive(page, id);
    }

    private Control FindControlRecursive(Control root, string id)
    {
    if (root.ID == id)
    {
    return root;
    }

    foreach (Control c in root.Controls)
    {
    Control t = FindControlRecursive(c, id);
    if (t != null)
    {
    return t;
    }
    }

    return null;
    }

    Call it like this

    Literal debug = (Literal)FindControlRecursive(“debug”);
    debug.Text = “asdasd”;

    Nice, thanks again

    Like

  17. Nice post! My own FindControlRecursive helped me out many times. Especially, when I deal with MasterPages. For example, one of such usage is shown in my post here – http://dotnetfollower.com/wordpress/2010/12/sharepoint-add-onchange-attribute-to-dropdownchoicefield/.
    Thank you!

    Like

  18. This article is very nice.
    Thank you very much.

    Like

  19. Sometimes developer must understand where to place this code.
    If you’re code in user control, you should use Parent.FindControl.
    I found this solution in my application.

    Like

  20. Is this still the case?
    MS JavaScript used to have that beautifull document.forms[0].inputs[5] syntax that everyone loves so much. Good to see it’s made a comeback in .net

    Like

  21. I copied the code above and I had to change from “private” to “protected” in order to use the function. I used it, but it still doesn’t work!!!

    Like

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.