Friday, April 4, 2008

Nested Master Pages

To demonstrate the use of Nested Master Pages, I will create an application that display the Home page and Project pages of the application. This application consists of 3 Master pages and 2 Content pages. Out of 3 master pages, 1 is the main or parent master page and 2 are secondary or child master pages. One content page is for Home page and second content page is for Project pages.

1) To start with, first you have to create a Parent or Main master page, named ParentMasterPage.master. Following is the code snippet for it:


<%@ Master Language="C#" AutoEventWireup="true" CodeFile="ParentMasterPage.master.cs"
Inherits="BCLMasterPage" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>ParentMasterPage Page</title>

<script runat="server">
protected void Page_Load(object sender, EventArgs e)
{
if (!object.Equals(Session["Projects"], null))
{
if (!object.Equals(Request.QueryString["deleteProjectName"], null))
{
string strPageLink = Request.QueryString["deleteProjectName"];

string strExistingProjects = Session["Projects"].ToString();
strExistingProjects = strExistingProjects.Replace(strPageLink + ";", "");

Session["Projects"] = strExistingProjects;
}

string strExistingProjs = Session["Projects"].ToString();
string[] strProjs = strExistingProjs.Split(new char[] { ';' });
for (int i = 0; i < strProjs.Length - 1; i++)
{
string strProj = strProjs[i];

StringBuilder strbNewTab = new StringBuilder();
strbNewTab.AppendFormat(@"<div style=""display:inline;background-color:Yellow;"">");
strbNewTab.AppendFormat(@"<a href=""ProjectDefault.aspx?projectName={0}"">{0}</a>", strProj);
strbNewTab.AppendFormat(@"<a href=""Home.aspx?deleteProjectName={0}"">", strProj);
strbNewTab.AppendFormat(@"<img alt=""Close"" src=""Images/Close.GIF"" />");
strbNewTab.AppendFormat(@"</a>");
strbNewTab.AppendFormat(@"</div>&nbsp;&nbsp;");

//string strExisting = divTabs.InnerHtml;
divTabs.InnerHtml += strbNewTab.ToString();
}


}
}
</script>

</head>
<body style="margin: 0px 0px 0px 0px;">
<form id="form1" runat="server">
<table border="1" cellpadding="0" cellspacing="0" style="height: 100%; width: 100%;">
<tr style="height: 60px;">
<td align="center" style="background-">
<asp:ContentPlaceHolder ID="ProjectHeader" runat="server">
<span style="font-weight: bold; ">PARENT MASTER PAGE SECTION</span>
</asp:ContentPlaceHolder>
</td>
</tr>
<tr style="height: 20px;">
<td>
<div id="divTabs" runat="server">
<div style="display: inline; background-color: Yellow;">
<a href="Home.aspx">Home</a></div>
&nbsp;&nbsp;
</div>
</td>
</tr>
<tr>
<td>
<asp:ContentPlaceHolder ID="ProjectBody" runat="server">
</asp:ContentPlaceHolder>
</td>
</tr>
</table>
</form>
</body>
</html>
Note: For time being please ignore the JavaScript section.

2) Then create secondary master page for Home page, named PersonalMasterPage.master. Following is the code snippet for it:

<%@ Master Language="C#" MasterPageFile="~/ParentMasterPage.master" AutoEventWireup="true"
CodeFile="PersonalMasterPage.master.cs" Inherits="PersonalMasterPage" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ProjectBody" runat="Server">
<table border="1" cellpadding="0" cellspacing="0" style="height: 660px; width: 100%;">
<tr>
<td align="center" style="width: 200px; height: 100%; background-">
<span style="font-weight: bold; ">PERSONAL LEFT <br />PANE SECTION</span>
</td>
<td valign="top" style="height: 100%;">
<asp:ContentPlaceHolder ID="ProjectData" runat="server">
</asp:ContentPlaceHolder>
</td>
</tr>
</table>
</asp:Content>

3) Now create another secondary master page for Project pages, named ProjectMasterPage.master. Following is the code snippet for it:

<%@ Master Language="C#" MasterPageFile="~/ParentMasterPage.master" AutoEventWireup="true"
CodeFile="ProjectMasterPage.master.cs" Inherits="ProjectMasterPage" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ProjectBody" runat="Server">
<table border="1" cellpadding="0" cellspacing="0" style="height: 660px; width: 100%;">
<tr>
<td align="center" style="width: 200px; height: 100%; background-">
<span style="font-weight: bold; ">PROJECT LEFT <br />PANE SECTION</span>
</td>
<td valign="top" style="padding:10 10 10 10;">
<asp:ContentPlaceHolder ID="ProjectData" runat="server">
</asp:ContentPlaceHolder>
</td>
</tr>
</table>
</asp:Content>

4) Create Home content page named Home.aspx that inherits Personal Master Page. Following is the code snippet for it:

<%@ Page Language="C#" MasterPageFile="~/PersonalMasterPage.master" AutoEventWireup="true"
CodeFile="Home.aspx.cs" Inherits="Home" Title="Home Page" %>

<asp:Content ID="Content1" ContentPlaceHolderID="ProjectData" runat="Server">
<table cellpadding="0" cellspacing="0" border="1" style="width: 100%;">
<tr>
<td valign="top">
<table border="0" cellpadding="5" cellspacing="0" style="width: 100%; margin: 10px 10px 10px 10px;">
<tr>
<td style="height: 20px;" valign="top">
<b>Project OverView Links</b>
</td>
</tr>
<tr>
<td valign="top">
<table cellpadding="0" cellspacing="0">
<tr>
<td>
<a href="ProjectDefault.aspx?projectName=Gene">Gene</a><br />
<a href="ProjectDefault.aspx?projectName=Cancer">Cancer</a><br />
<a href="ProjectDefault.aspx?projectName=Brain">Brain</a>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td>
<br />
<em>Other Data Section</em>
</td>
</tr>
</table>
</asp:Content>

5) Create Project content page named ProjectDefault.aspx that inherits Project Master Page. Following is the code snippet for it:

<%@ Page Language="C#" MasterPageFile="~/ProjectMasterPage.master" AutoEventWireup="true"
CodeFile="ProjectDefault.aspx.cs" Inherits="ProjectDefault" Title="Project Page" %>

<asp:Content ID="Content1" ContentPlaceHolderID="ProjectData" runat="Server">
<table cellpadding="0" cellspacing="0" border="1" style="width: 100%;">
<tr>
<td>
<div style="color: Blue; font-style: italic; font-weight: bold;" id="divPage" runat="server">
</div>
<b><em>Tab is selected</em></b>
</td>
</tr>
<tr>
<td>
<br />
<em>Other Project Data</em>
</td>
</tr>
</table>
</asp:Content>
CS file code:

using System;
using System.Data;
using System.Configuration;
using System.Collections;
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 ProjectDefault : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
string strRequestedPage = Request.QueryString["projectName"];
divPage.InnerHtml = strRequestedPage;

if (object.Equals(Session["Projects"], null))
{
Session["Projects"] = strRequestedPage + ";";
}
else
{
string strExistingProjs = Session["Projects"].ToString();
if (!strExistingProjs.Contains(strRequestedPage))
Session["Projects"] = strExistingProjs + strRequestedPage + ";";
}
}
}




Following are the snapshots for Home and Project pages:











Top Green color section refers to Main Master Page and left Gray and Olive color sections refers to Personal Master Page and Project Master Page section respectively in above two figures.


Following is the snapshot of solution explorer of above application:






Now how the above application works:

I have created 3 links in Home page, on clicking of which I am entering its value in session and opens the Project page with modified query string. Similarly on clicking the cross of tab I am deleting that project entry from session and redirect the application to home page.

2 comments:

Anonymous said...

I need to pass two integer values from Master Page to Sub Master Page. Please provide help regarding that.

Avinash said...

Hi Vipin,

You can use either one of the approach:
1) Use Session/ViewState/QuerString/etc... to store integer values.
2) Store integer value in a control (may be hidden one) and use following code in content page:
this.Page.Master.FindControl("controlID");

Also refer following link (for two way data passing between Master and Content Page):
http://aspnet.4guysfromrolla.com/articles/013107-1.aspx

Also consider the page life-cycle in case of Master-Content page scenario,
otherwise you may not get the required data.

~ Avinash

Google