MasterPages: Improved Version
Overview
MasterPages is the most flexible and easiest to use of
Page Template solutions,
and since it was created by Microsoft it will likely someday be in ASP.NET itself.
However, the
original demo lacks designer support, suffers from poor performance,
and is NamingContainer "happy", giving IDs like Container:_ctl0:Region:Control.
This article demos an improved version of MasterPages that has designer support,
better performance without the flexible but annoying NamingContainer "problem",
and adds the ability to define a default content region and default template file.
Creating a Template
To create a MasterPages Template you start by creating an ASP.NET User Control
and then add your common page layout that you intend all of your pages share.
Then you mark any spots in the layout that will be defined in individual pages
with a "ContentRegion" control, along with a unique ID to be matched later.
You can include multiple ContentRegions, and you can add default content inside
ContentRegions that will be used for pages that do not contain a matching ID.
Note the Register directive and control syntax is automatic with drag-n-drop.
Listing 1: Creating a Template
<%@ Control %>
<%@ Register TagPrefix="Wilson" Assembly="WilsonMasterPages"
Namespace="Wilson.MasterPages" %>
<html>
<head>
<title>MasterPages</title>
</head>
<body>
<h1><wilson:contentregion id="MPHeader" runat="server">
Page Header</wilson:contentregion></h1>
<form id="frmMain" method="post" runat="server">
<wilson:contentregion id="MPContent" runat="server">
Default Content</wilson:contentregion>
</form>
<h2><wilson:contentregion id="MPFooter" runat="server">
Page Footer</wilson:contentregion></h2>
</body>
</html>
Defining the Defaults
You can define two MasterPages default settings in your app's web.config file.
The Wilson.MasterPages.TemplateFile app-setting is used to specify the default
User Control that will be used for all MasterPages Templates when not specified.
The Wilson.MasterPages.DefaultContent app-setting is used to specify the default
ContentRegion ID so you can add its content directly to the MasterPage control.
The concept of a default ContentRegion is not likely to be added by Microsoft,
and its use is optional even here, but I personally find it a useful concept.
Listing 2: Defining the Defaults
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="Wilson.MasterPages.TemplateFile" value="~/Template.ascx" />
<add key="Wilson.MasterPages.DefaultContent" value="MPContent" />
</appSettings>
<system.web>
<!-- Normal web.config settings go here -->
</system.web>
</configuration>
Using the Template
To use the MasterPage Template you start by creating an empty ASP.NET Page,
stripping out all the standard content that the wizard automatically adds.
Then you add a "MasterPage" control, possibly with a TemplateFile attribute.
Next, directly add the content of the default ContentRegion to the MasterPage.
Finally, add other "ContentRegion" controls to the MasterPage, being careful
to match up their IDs with the IDs that were specified in the Template itself,
skipping any ContentRegions that you prefer to accept their default content.
Listing 3: Using the Template
<%@ Page %>
<%@ Register TagPrefix="Wilson" Assembly="WilsonMasterPages"
Namespace="Wilson.MasterPages" %>
<wilson:masterpage runat="server" masterpagefile="Template.ascx">
<wilson:contentregion id="MPHeader" runat="server">
Sample Page</wilson:contentregion>
Real Content for the Default ContentRegion
</wilson:masterpage>
Source Code Notes
The original MasterPages demo had both ContentContainer and Region controls
inherit from PlaceHolder and INamingContainer, with Content inheriting Panel.
However, PlaceHolders are not intended for designer support, only run-time,
so my MasterPage inherits from HtmlContainerControl, with a ReadWrite Designer.
I combined the Content and Region controls into a single ContentRegion control,
which inherits from Panel, and I added a "WhiteSmoke" background color to it.
I also removed the begin and end "div" tags and the INamingContainer interface.
Conclusion
This custom version of Microsoft's MasterPages demo Page Templating controls
now has design-time support and performs faster, and adds a few default settings.
There is still no "visual" inheritance; that requires built-in support in VS.NET.
It should be noted that the removal of the NamingContainers is making it faster
and avoiding the annoying hierarchical control names, but this comes at a loss
of some flexibility -- no guaranteed unique names and no repeating templates.
Finally
see my website
for a demo of making the templates user-selectable as well.
Author Bio
Paul Wilson is a software architect in Atlanta, currently with a medical device company.
He specializes in Microsoft technologies, including .NET, C#, ASP, SQL, COM+, and VB.
His
WilsonWebForm
Control allows Multiple Forms and Non-PostBack Forms in ASP.NET.
He is a Microsoft MVP in ASP.NET and is also recognized as an ASPFriend's
ASPAce/ASPElite.
He is a moderator on Microsoft's
ASP.NET Forums, as well as one of the top posters.
He is certified in .NET (MCAD), as well as also holding the MCSD, MCDBA, and MCSE.
Please visit his website,
www.WilsonDotNet.com,
or email him at
Paul@WilsonDotNet.com.