Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Inheritance and Nested Master Pages

0.00/5 (No votes)
10 May 2007 1  
An article is about editing inherited properties of top level master page from .aspx code

Introduction

This article is about small problem I got stuck when I tried to use inheritance with Nested Master Pages. If you looking for something general about Master Pages please try to see this article Inside Master Pages

Problem description

Well, here is my situation

Screenshot - NestedMasterPages.gif

As you can see I try to inherit Child.Master from Main.Master and then use Child.Master in MyPage.

Main.master

<%@ Master Language="C#" AutoEventWireup="true" 
    CodeBehind="Main.master.cs" Inherits="Master.Main" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" 
       "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">

<head id="mainHead" runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="mainForm" runat="server">
        <asp:Literal ID="TopMessageLiteral" runat="server" />
        
        <div id="content">           
            <asp:contentplaceholder id="cphMain" runat="server" />
    </div>
    </form>
</body>
</html>

Child.master

<%@ Master Language="C#" MasterPageFile="~/Master/Main.master" AutoEventWireup="true" 
    CodeBehind="Child.master.cs" Inherits="Master.Child" %>
<%@ MasterType VirtualPath="~/Master/Main.master" %>
<asp:Content ID="cntMain" ContentPlaceHolderID="cphMain" Runat="Server">
    <div id="left">       
        <asp:contentplaceholder id="cphLeftCol" runat="server" />
    </div>  
    
    <div id="right">
        <asp:contentplaceholder id="cphRightCol" runat="server" />    
    </div>
</asp:Content>

MyPage

<%@ Page Language="C#" MasterPageFile="~/Master/Child.master" AutoEventWireup="true" 
    Inherits="MyPage" Title="Untitled Page" Codebehind="MyPage.aspx.cs" %>
<%@ MasterType VirtualPath="~/Master/Child.master" %>

<asp:Content ID="cntLeftCol" ContentPlaceHolderID="cphLeftCol" Runat="Server">
    <p>test left</p>
</asp:Content>
<asp:Content ID="cntRightCol" ContentPlaceHolderID="cphRightCol" Runat="Server">
    <p>test right</p>
</asp:Content>

Code-behinds please see below:

//Main.master

//-------------

public partial class Main : System.Web.UI.MasterPage {
  
  private string _topMessage;

  public string TopMessage {
    get { return _topMessage; }
    set { _topMessage = value; }
  }

  protected void Page_Load(object sender, EventArgs e) {
    TopMessageLiteral.Text = TopMessage;
  }
}

//Child.master 

//------------

public partial class Child : Main {

   protected new void Page_Load(object sender, EventArgs e) {
               
   }

}

//MyPage.aspx 

//----------

public partial class MyPage: System.Web.UI.Page {

  protected void Page_Load(object sender, EventArgs e) {
    Master.TopMessage = "My top message";
  }
}
It looks like good code but it doesn't work. My TopMessage will never be shown. If you try to debug this code you'll see that when you instantiate TopMessage property in MyPage.Page_Load all is going well and value is successfully saved to _topMessage variable. But when it will be read from Main.Page_Load it is empty. Frankly, I don't know why. I have some guesses only. But it seems I found solution.

Solution

The trick is to use Context.Items collection.
//Main.master

//-------------

public partial class Main : System.Web.UI.MasterPage {
  
  public string TopMessage {
    get {
       if (Context.Items["_topMessage"] != null)
          return Context.Items["_topMessage"].ToString();
       else
          return string.Empty;
    }
    set {
        Context.Items["_topMessage"] = value;
    }
  }

  protected void Page_Load(object sender, EventArgs e) {
    TopMessageLiteral.Text = TopMessage;
  }
}
In this way TopMessage value will never be lost.

One More Solution

Suggested by Irwan Hassan technic need not Main.master <- Child.master inheritance

//MyPage.aspx 

//----------

public partial class MyPage: System.Web.UI.Page {

  protected void Page_Load(object sender, EventArgs e) {
    Master.Master.TopMessage = "My top message";
  }
}

History

May 09, 2007: just add a piece of code to play experiments

May 10, 2007: add one more solution

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here