Changing MasterPages dynamically is a simple task, but there is a catch. MasterPage can be changed in PreInit page or earlier. At this stage control tree is not constructed yet. The question is: "How can we use postback event to change MasterPage?" Usual solution for this problem is to save selected MasterPage file name into session, reload page and in PreInit set MasterPage according to persisted value. This works but requires additional roundtrip. Another solution is to intercept postback events in PreInit and process it, so here it is:
ASPX:
@ Page MasterPageFile="~/MasterPage.master" Language="C#" AutoEventWireup="true" CodeFile="Default2.aspx.cs" Inherits="Default2" %>
<asp:Content ContentPlaceHolderID="ContentPlaceHolder1" runat="server">
<div>
<asp:DropDownList ID="MasterSwitch" runat="server" AutoPostBack="true">
<asp:ListItem Text="Simple Layout" Value="MasterPage.master">asp:ListItem>
<asp:ListItem Text="Complex Style" Value="MasterPageComplex.master">asp:ListItem>
<asp<:DropDownList>
<div<>>
<asp<>:Content>
Codebeside:
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
public partial class Default : System.Web.UI.Page
{
protected void Page_PreInit(object sender, EventArgs e)
{
switchMaster();
}
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
Session["MasterSwitch"] = this.MasterSwitch.UniqueID;
}
}
private void switchMaster()
{
if (IsPostBack)
{
// Get control that fire postback event
string eventTarget = Request.Form["__EVENTTARGET"];
if (String.IsNullOrEmpty(eventTarget))
return;
// At this stage we don't have control tree yet,
// so we'll use previosly saved control ID
string switchControlName = (string)Session["MasterSwitch"];
if (String.IsNullOrEmpty(switchControlName))
return;
if (String.Compare(eventTarget, switchControlName, true) != 0)
return;
setMaster(Request.Form[eventTarget]);
}
}
private void setMaster(string masterName)
{
if (String.IsNullOrEmpty(masterName))
return;
// In real implementation some logic to convert
// selected value into real MasterPage File Name should be here
if (String.Compare(this.MasterPageFile, masterName, true) != 0)
this.MasterPageFile = masterName;
}
}
If you have any additional tips, tricks etc that you would like me to post to my blog, please email them to me at chrisw_88@hotmail.com