Eric Wise

Sponsors

The Lounge

Wicked Cool Jobs

Blogs I Read

Fun & Games

Advertisement

Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
Basics: Master Page FAQ

I lurk around some of the joel and microsoft forums from time to time and every once in a while I pop up to the surface to answer some .net questions.  I've been meaning for a while to compile some of the basic questions I see pop up frequently about master pages.

How can my page talk to my master page?

Couple ways to do this.  Page.Master will give you a loose reference to whatever the master page is, and then you can use FindControl() to locate and manipulate whatever controls you need to.  Personally, I do not like this method because FindControl is prone to typos, and won't raise a compiler error if someone takes that control out or renames it. It also makes the page responsible for controls in the master, I think the master should be in charge of that.

The better way to accomplish this is to get a strong reference to your master page, and then call public methods to set and query values.  There are two ways to go about this.  In method one, in your .aspx page below the <% page %> directives you can put the following directive:

<%@ MasterType VirtualPath="~/MyMaster.master" %>

Now when you type Page.Master. intellisense will fire up all the methods in your master page that you have made available.  You can also cast Page.Master yourself as follows:

((MyMaster)Page.Master).Foo()

 

Can I dynamically set a master page at runtime?

Certainly!  Use the page_preinit event:

void BasePage_PreInit(object sender, EventArgs e)
{
     MasterPageFile = "~/MyMaster.master";
}

 

What the hell is up with order of events with master pages?

Maybe you should ask Scott Guthrie.  Just remember to watch out for Page_Load and Page_Init.  If you expose a Page_Load in the master and content, the content will fire first.  For Page_Init, the master will fire first.  Init bubbles from the inside out, and it's a common mistake by newbie asp .net developers to think that because the master page visually "wraps" content that it is outside.  In reality during execution the master page is on the inside.  =)

 

My control names are all messed up!

Because you can have multiple content names and .net needs to ensure that all IDs are unique, you'll find that controls inside the content page will be prepended with some goo that makes them unique.  This can cause issues if you are using javascript which references controls.  The solution to this is to use the ClientId property of your server controls.  Here's an example of showing and hiding a server side <div> element with javascript:

<script type="text/javascript" language="javascript">
            function showDIV()
            {
              document.getElementById("<%=dvMyDiv.ClientID %>").style.display="";
            }
           
            function hideDIV()
            {
              document.getElementById("<%=dvMyDiv.ClientID %>").style.display="none";
            }

</script>

 


Posted Wed, Aug 2 2006 8:43 AM by Eric Wise

[Advertisement]

Comments

Scott wrote re: Basics: Master Page FAQ
on Wed, Aug 2 2006 11:52 AM
Here is another article that will help out: http://odetocode.com/Articles/450.aspx
CallContext wrote An interesting master page trick
on Fri, Aug 4 2006 1:16 AM
I didn't know you could do this (courtesy of Eric Wise from CodeBetter.com). Apparently, you can get the original, unmangled control ID using the ClientID property of the control.
Dan wrote re: Basics: Master Page FAQ
on Mon, Aug 14 2006 4:20 AM
Casting to the masterpage may fail if your website is compiled into several assemblies because it isnt certain that the assembly the page is in references the assembly the master page is in, if you want to cast on-the-fly you either need to make sure its all in one assembly, or use an interface from App_Code which the masterpage implements.
Aaron Edwards wrote re: Basics: Master Page FAQ
on Fri, Mar 23 2007 2:39 PM

Using scott's article, posted above, I ran into the following snag...

I'm building a Content Management System that allows the user to dynamically change the MasterPageFile property of a page.  I have 4 MasterPages setup that look different, but have all the same code on them.  Each of them inherits from a base class I defined called BaseMasterPage.  

Each MasterPage has this one user control on it.  I handle the events of the control in the MasterPage, using the RaiseBubbleEvent method inside the user control.

The problem is that the user control is bubbling its events to the MasterPage declared in the @Page directive, not the one we dynamically changed to during the page's PreInit event. Then events on the User Control bring back controls from the wrong MasterPage, including ones that weren't originally in the ViewState.  Since I'm using an UpdatePanel, I get the "Cannot Load ViewState" error.

How can I tell the control who its daddy is?

Thanks.

Aaron Edwards wrote re: Basics: Master Page FAQ
on Fri, Mar 23 2007 4:31 PM

Nevermind, I figured this out.  When you change the MasterPageFile property in the page's PreInit event, you don't want to only do it if IsPostBack=False.  Thanks.

Rupesh Kumar Tiwari wrote re: Basics: Master Page FAQ
on Wed, May 30 2007 7:11 AM

How can i access the method of the masterpage inside the web user control.

i have made one masterpage, i have one public method on the master page. I have added one usercontrol on the masterpage, but i want to access the method of the masterpage from the usercontrol. Is it possible to get the object of the master page inside the usercontrol.

Thanks in advance.

tmoneyj wrote re: Basics: Master Page FAQ
on Tue, Jun 5 2007 2:49 PM

Rupesh Kumar Tiwari,

You should bubble the event to the master page.

in the user control register the event

public event EventHandler Login;

then create the event when a button is pushed on the user control like this

       if (Login != null)

         Login(this, e);

Then in the master page register the event like this, on pageLoad pageInt like this

LoginControl1.Login += new EventHandler(Login);

Then create the method to handle the event in the master page.

 protected void Login(object sender, EventArgs e)

 {

   do whatever you need to do in the mater page

 }

Tim Erwin wrote re: Basics: Master Page FAQ
on Mon, Nov 19 2007 12:28 PM

@CallContext - I had to use .ID instead of .ClientID to get the original unmangled version.

Devlicio.us