Click here to Skip to main content
15,887,256 members
Articles / Web Development / ASP.NET

Accessing Controls on Nested Master Pages from Content Pages using Dynamic Polymorphism

Rate me:
Please Sign up or sign in to vote.
2.09/5 (3 votes)
30 Oct 2007CPOL3 min read 45.2K   20   8
How to access controls on nested master pages from content pages using dynamic polymorphism without casting to master page classes.

Introduction

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 FindControls() method.

Background

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:

  1. BaseMasterPage.master, code-behind BaseMasterPage.master.cs
  2. SubMasterPage.master, code-behind SubMasterPage.master.cs, master file: BaseMasterPage.master
  3. MyPage.aspx, code-behind MyPage.aspx.cs, master file: SubMasterPage.master

Having set up the hierarchy as above, create a super base class called SuperBaseMaster.cs.

C#
public class SuperBaseMaster : MasterPage
{
}

Override the 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

C#
public Control BaseFindControl(string id)
{
    return base.FindControl(id);
}

public override Control FindControl(string id)
{
    return FindMyControl(id, this);
}

private Control FindMyControl(string id, BaseMasterPage master)
{
    //If currentmaster is null, then the control with "id" is not found
    //so return null


    if (master == null) return null;
    //Call the inbuilt base FindControl

    Control ctl = master.BaseFindControl(id);

    if (ctl == null)
    {
        //Call the FindMyControl method recursively

        return FindMyControl(id, (BaseMasterPage)master.Master);
    }

    return ctl;
}

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.

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:

ASP.NET
<body> <form id="form1" runat="server">
<div>
<asp:TextBox ID="myTextBoxID" runat="server"></asp:TextBox>
<asp:contentplaceholder id="ContentPlaceHolder1" runat="server">
</asp:contentplaceholder> </div>
</form></body> 

To find this textbox control from our content page in the traditional way, you would do:

C#
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:

C#
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.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect
United States United States
Software Architect

Comments and Discussions

 
QuestionEsiest Way To Find Control from Nested Master Pages Pin
Maulik Anand6-Feb-13 15:41
Maulik Anand6-Feb-13 15:41 
Generalit is not working Pin
kirankkk200919-Oct-10 2:57
kirankkk200919-Oct-10 2:57 
GeneralFinding controls within the content placeholder Pin
Mr. C. Simon17-Mar-09 7:53
Mr. C. Simon17-Mar-09 7:53 
GeneralOOP Pin
otijim6-Mar-09 11:01
otijim6-Mar-09 11:01 
QuestionGreat work, but a question... Pin
junglemason1-Feb-08 13:55
junglemason1-Feb-08 13:55 
GeneralRe: Great work, but a question... Pin
Gyan Jadal4-Feb-08 14:39
Gyan Jadal4-Feb-08 14:39 
GeneralAwesome! Pin
Member 385964013-Jan-08 14:30
Member 385964013-Jan-08 14:30 
GeneralEasier Pin
ttuBrant12-Nov-07 10:37
ttuBrant12-Nov-07 10:37 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.