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:
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;
}
Related Posts
- ASP .NET 2.0, GridViews, HyperLinkField, and JavaScript I’ve found some interesting notes on ASP .NET’s GridView, it’s limitations and work arounds. For work I was looking for a way to execute JavaScript from clicking a link on a GridView Cell. An example would be to having a list of transactions and wanting to click a link to...
- ASP .NET GridView Access to Data In Code There are situations where you want to gain access to the GridView’s DataSet to display extra information outside of the GridView. I found the following code to work the best for me. You can get the information from the DataSource of a GridView by doing the following: DataView dv =...
- Retrieve Current Module/Controller/Action inside View Script / Layout Script Before I forget to do this again I’m going to make a post on how to get the current Module, Controller, and Action while inside a View Script or Layout Script. Here is the most correct way to do it: Now, here is the incorrect way I attempted to do...
thx for that post, it was quite helpful and made me understand the innner workings of asp.net a little better
Thank you sooooooooooooooooo much
You’re welcome
I haven’t used ASP.NET for almost a year now, but I’m glad my findings still help people out.
Thank you. Thank you. Thank you.
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”?
Thank you.
This is great!
Thanks so much!
Thank Heavens! I spent a little bit of time on this and was pulling my hair out. Thanks for saving me potential hours!
Thank you very much!!! What a life saver.
Replace Page.FindControl() to NamingContainer.FindControl()
Thank you very much!!!
Yes, many thanks !
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
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
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
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!
This article is very nice.
Thank you very much.