Tips for Nested Master Pages and VS 2005 Design-Time
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:
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):
<%@ 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.
Update: Brian also pointed out to me that you can leave the MasterPageFile attribute value as "" and the designer will then automatically render a test master page that just lists all of the content-placeholder controls in editable regions. This might allow you to avoid having to define a test master page for your site.
Here is a simple sample that shows all this working (you can switch the default.aspx page to use either the submaster.master or submaster2.master page that is based on mainmaster.master).
Hope this helps and is useful,
Scott
P.S. The new Microsoft Expression “Quartz” Web Designer tool *will* also support editing pages based on nested master-pages in design-time, and this will also show up in the next release of Visual Studio (code-name Orcas).