ASP.NET 2.0 MasterPages and FindControl()
The problem is that when you use MasterPages the page hierarchy drastically changes. Where a simple this.FindControl() used to give you a control instance you now have to drill into the container hierarchy pretty deeply just to get to the content container.
So in the past I might have done this in my C# base class:
protected Label lblError = null;
protected DataGrid dgItemList = null;
protected void AssignControls()
{
this.lblError = this.FindControl("lblError") as Label;
this.dgItemList = this.FindControl("dgItemList") as DataGrid;
}
you now have to drill into the containership with code like this:
protected void AssignControls()
{
this.lblError = this.Master.FindControl("Content").FindControl("lblError") as Label;
this.dgItemList = this.Master.FindControl("Content").FindControl("dgItemList") as DataGrid;
}
This isn't so bad, except when you're trying to figure out how to get to your controls.
It really seems lame that Microsoft hasn't added a recursive FindControl() method to the Control class that drills into child containers. While this certainly isn't optimal in terms of performance it sure would make life a lot easier in a lot of situations, and this surely is one of them.
Not exactly rocket science to create a method that does this:
///
/// Finds a Control recursively. Note finds the first match and exists
///
///
///
///
public static Control FindControlRecursive(Control Root, string Id)
{
if (Root.ID == Id)
return Root;
foreach (Control Ctl in Root.Controls)
{
Control FoundCtl = FindControlRecursive(Ctl, Id);
if (FoundCtl != null)
return FoundCtl;
}
return null;
}
with this the code becomes:
///
/// Assigns controls from the subclassed control to this instance so
/// we always can access the controls in our base class.
///
protected void AssignControls()
{
this.lblError = wwWebUtils.FindControlRecursive(this.Master,"lblError") as Label;
this.dgItemList = wwWebUtils.FindControlRecursive(this.Master, "dgItemList") as DataGrid;
}
Although this is easier, I suspect it's better to do the explicit thing if that option is available to you as it probably has better performance. Also I suspect Microsoft didn't include this sort of a function in ASP.NET natively because there's potential ambiguity here – there could be more than one control Id that matches a name.
You can also refer "FindControl not working in content page" http://forums.asp.net/p/1000865/1941105.aspx
Jak
So in the past I might have done this in my C# base class:
protected Label lblError = null;
protected DataGrid dgItemList = null;
protected void AssignControls()
{
this.lblError = this.FindControl("lblError") as Label;
this.dgItemList = this.FindControl("dgItemList") as DataGrid;
}
you now have to drill into the containership with code like this:
protected void AssignControls()
{
this.lblError = this.Master.FindControl("Content").FindControl("lblError") as Label;
this.dgItemList = this.Master.FindControl("Content").FindControl("dgItemList") as DataGrid;
}
This isn't so bad, except when you're trying to figure out how to get to your controls.
It really seems lame that Microsoft hasn't added a recursive FindControl() method to the Control class that drills into child containers. While this certainly isn't optimal in terms of performance it sure would make life a lot easier in a lot of situations, and this surely is one of them.
Not exactly rocket science to create a method that does this:
///
/// Finds a Control recursively. Note finds the first match and exists
///
///
///
///
public static Control FindControlRecursive(Control Root, string Id)
{
if (Root.ID == Id)
return Root;
foreach (Control Ctl in Root.Controls)
{
Control FoundCtl = FindControlRecursive(Ctl, Id);
if (FoundCtl != null)
return FoundCtl;
}
return null;
}
with this the code becomes:
///
/// Assigns controls from the subclassed control to this instance so
/// we always can access the controls in our base class.
///
protected void AssignControls()
{
this.lblError = wwWebUtils.FindControlRecursive(this.Master,"lblError") as Label;
this.dgItemList = wwWebUtils.FindControlRecursive(this.Master, "dgItemList") as DataGrid;
}
Although this is easier, I suspect it's better to do the explicit thing if that option is available to you as it probably has better performance. Also I suspect Microsoft didn't include this sort of a function in ASP.NET natively because there's potential ambiguity here – there could be more than one control Id that matches a name.
You can also refer "FindControl not working in content page" http://forums.asp.net/p/1000865/1941105.aspx
Jak
Comments
Post a Comment