Republished With Permission - Original Article
One of the cool advanced features of the new Master Pages
feature in ASP.NET 2.0 is the ability to nest them. For example, you could
define a top-level master-page called “MainMaster.master” that defines a common
logo header and footer, and defines a content-placeholder for the page called
“content”. You could then define two sub-masters beneath it – one that
provides a two-column layout model for the content (“TwoColumnMaster.master”),
and one that provides a three-column layout model
(“ThreeColumnMaster.master”). These two nested-master pages could then use the
MainMaster.master file as the root master, and only adjust the layout within
its content section (each would fill in the "content" placeholder and
in turn add their own content-placeholders for sub-pages within it). The
benefit of this approach is that if a designer ever changed the logo or
top-level design of the site, they only have to update one file
(MainMaster.master) and then have every page on the site automatically pick it
up regardless of what master file they were based on.
This nested model is pretty cool and powerful, and allows
arbitrary levels of nesting. The only downside is that VS 2005 only supports
nested master page editing in source-view, and doesn’t support it in the
WYWSIWYG designer (note: obviously it does support editing them when the
master-pages are not nested).
There is a cool tip/trick, though, that will allow you to
load a design-surface for a page that uses nested master-pages. This will
allow you to use all of the control-designers and smart-tasks in design-view
for the page (for example: to perform data-binding, auto-format things, and use
any of the control wizards), and not have to change any-code to test it at
runtime.
The tip/trick works by adding a base-page class to your
project or solution that defines a new property called “RuntimeMasterPageFile”
of type string. The base-class then overrides the page’s “OnPreInit” method
and uses this property to set the Page object’s MasterPageFile at runtime:
Listing 1
public class BasePage: System.Web.UI.Page
{
private string runtimeMasterPageFile;
public string RuntimeMasterPageFile
{
get
{
return runtimeMasterPageFile;
}
set
{
runtimeMasterPageFile = value;
}
}
protected override void OnPreInit(EventArgs e)
{
if (runtimeMasterPageFile != null)
{
this.MasterPageFile = runtimeMasterPageFile;
}
base.OnPreInit(e);
}
}
Once a code-behind class derives from this base class, it
becomes possible for a developer to set this “RuntimeMasterPageFile” property
in the .aspx file’s <%@ Page %> directive (note: the CodeFileBaseClass
also needs to be set to the base class to enable this):
Listing 2
<%@ Page Language="C#"
MasterPageFile="~/Test.master"
RuntimeMasterPageFile="SubMaster.master"
CodeFileBaseClass="BasePage" AutoEventWireup="true"
CodeFile="Default.aspx.cs" Inherits="_Default"
Title="My Page Title" %>
You’ll notice that the above page now has two master-page
file directives – the usual “MasterPageFile” directive that VS will use at
design-time, and then the custom RuntimeMasterPageFile directive that will
override this at runtime. What this allows you to do is point the page at a
“test.master” file at design-time that is a single-nested page with
contentplaceholder controls that match the names in your nested master. You
can then switch to design-view and edit the content and all controls on your
page. When you run the page, though, it will use the nested “submaster.master”
(or any other master page you specify) to run.