简体   繁体   中英

Change the master page when clicking a button in master

I am having three master pages like Master-Green, Master-Bule, Master-Red . In each master page having three buttons named as green, blue and red .
Now my default master is green ,

It's assigned a page Default.aspx . At this time three button also display on the top.

How to make so clicking "blue" button means the Master-Blue shold be master page for the current page?

  1. In the Master Page use input type submit button

< input type=" submit " name=" btnGreen " value="Green" />

< input type=" submit " name=" btnBlue " value="Blue" />

2.Then from the code behind you can check the name of the button clicked, in the Request object in the Page_PreInit event

public partial class Default : System.Web.UI.Page
{
    protected void Page_PreInit(object sender, EventArgs e)
    {
        if (Request["btnGreen"] != null)
        {
            Page.MasterPageFile = "/Green.Master";
        }
        else if (Request["btnBlue"] != null)
        {
            Page.MasterPageFile = "/Blue.Master";
        }
    }

}

Dealing with dynamic master pages might look easy at first sight but it's a little tricky.

Consider the following:

  • A MasterPage is actually considered as a child control of the page, therefore, its life-cycle is like any other control on the page

  • In order to change the MasterPage at runetime, it has to be done in the PreInit event of the page (remember that controls do not have this event, therefore the MasterPage does not have it either)

  • As a reminder, the PreInit , Init , and Load events of the page life cycle work as follows: The page's PreInit event is fired, followed by all the Init events of the page's child controls (including the MasterPage), when all child Init events have been raised, the page's Init event is fired and finally the page's InitComplete event is fired indicating all Init events have been processed. The Load events work the other way around, the page's Load event is fired first, followed by all the child control's Load events and at the end, the page's LoadComplete event.

  • The Post back event that caused the page's post back is raised after all child control's Load events have been fired but before the page's LoadComplete event

  • In the PreInit event you do not have access to the page ViewState

Source: http://msdn.microsoft.com/en-us/library/ms178472.aspx

Quick Look:

在此输入图像描述

So why is this so important?

In your example you have three buttons, each time a button is pressed, you need to change the MasterPage, but the MasterPage must be changed in the PreInit event of the page, but your button handler is processed after that, so the tricky part is to call Server.Transfer to re-process the page.

Note. Since you are allowing the user to personalize the MasterPage, you need a way store his preferences, usually you would use a cookie, or a database. In this sample I am going to use the Session object for simplicity but you can change it to fit your needs.

So this would look something like:

Master page code behind

protected void blueMasterPage_Click(object sender, EventArgs e)
{
    this.Session["master"] = "BlueMasterPage";
    this.Server.Transfer(this.Request.RawUrl);
}

In the page code behind

protected void Page_PreInit(object sender, EventArgs e)
{
    if (this.Session["master"] != null)
    {
        this.MasterPageFile = string.Format("~/{0}.master", (string)this.Session["master"]);
    }
}

Note: If you do not use Server.Transfer you won't see the changes to the page's MasterPage until the next time you do a post to the page

So this was tricky, and in my opinion, we should be able to do the same easier, one more time the ASP.Net page's life cycle doesn't help at all.

You can always follow the @AndreCalil suggestion about using just one master page and different CSS layouts for your site

Edit 1

One thing that I forgot to mention, is that you need to set the master page in all your pages consuming the dynamic MasterPage, so the best way to do it, is create a base page and inherit from it, and in the base page write the code in the PreInit event to set the MasterPage

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM