This article explains how to find controls on any number of levels of Master pages using a single method without typecasting or doing
Master.Master. The concept used here is Dynamic Polymorphism by overriding the
There are situations where you have just added nesting to Master pages in your application and some controls have been moved to the super master page. All your
FindControl methods which were called using
Page.master would break, and you would now have to do
Page.Master.master plus the type cast. I have devised a method so that none of the code is affected. Only thing you need to do is add some code to the newly created Master file. I find it useful to have a single method which finds for the control scanning through the hierarchy of master pages above the content page.
Using the code
I have tried to make use of dynamic polymorphism here. As we know, every
Page class or master page class has an inbuilt
FindControl method which finds controls in that page. To have the
FindControls method find controls anywhere in the hierarchy, I have simply done the following.
Let's say we have two levels of nesting:
BaseMasterPage.master, code-behind BaseMasterPage.master.cs
SubMasterPage.master, code-behind SubMasterPage.master.cs, master file:
- MyPage.aspx, code-behind MyPage.aspx.cs, master file:
Having set up the hierarchy as above, create a super base class called SuperBaseMaster.cs.
public class SuperBaseMaster : MasterPage
FindControl method in SuperBaseMaster.cs as shown in the code snippet below. I have also used a recursive method to find the control up to the base master page.
Note: For this to work, all the master pages code-behind classes must derive from a common super base class which is derived from
MasterPage, as shown above
public Control BaseFindControl(string id)
public override Control FindControl(string id)
return FindMyControl(id, this);
private Control FindMyControl(string id, BaseMasterPage master)
if (master == null) return null;
Control ctl = master.BaseFindControl(id);
if (ctl == null)
return FindMyControl(id, (BaseMasterPage)master.Master);
Here in the above code,
BaseFindControl does what the original
FindControl method used to do. Since we have overridden
FindControl, we need some way to get to the original one. Hence this method.
Next, the overridden
FindControl will call our recursive method
FindMyControl will first try to find the control on the current master which is passed as a parameter. If the control is not found, then it calls itself again with the next higher level master (
master.Master), and this goes on till the control is found. If not, a
null is returned in the end.
So far so good.
If you have come this far, then let's see how to call our overridden
FindControl method. For this, let's assume that we want to find a textbox control with the ID "
myTextBoxID". And, this control exists on the
BaseMasterPage. Here is the code for it:
<body> <form id="form1" runat="server">
<asp:TextBox ID="myTextBoxID" runat="server"></asp:TextBox>
<asp:contentplaceholder id="ContentPlaceHolder1" runat="server">
To find this textbox control from our content page in the traditional way, you would do:
SubMasterPage subMaster = (SubMasterPage)this.Page.Master;
BaseMasterPage baseMaster = (BaseMasterPage)subMaster.Master;
TextBox mytextBox = (TextBox)baseMaster.FindControl("myTextBoxID");
And now, using our dynamic method, you would do:
TextBox myTextBox = (TextBox)this.Page.Master.FindControl("myTextBoxID");
That's it. One line. For any level of hierarchy, it will be just one line. And, no typecasting needed (although there are other ways to avoid typecasting, I would not go into the details of that).
The main point here is, this will act as a generic method for the master pages, and you don't have to worry when controls are moved up and down the hierarchy, which happens when the masters are refactored.
Hope this will be useful for those working with refactoring nested master pages. Comments are welcome.