Chapter 9 How to use master pages Murach’s ASP.NET 3.5/C#, C9 © 2008, Mike Murach & Associates, Inc. Slide 1 Objectives Applied Use a master page to provide the elements that are the same for a set of content pages. Use a parent master page to provide the elements that are the same for a set of content pages and child master pages to provide the elements that are the same for subsets of content pages in that set. Murach’s ASP.NET 3.5/C#, C9 © 2008, Mike Murach & Associates, Inc. Slide 2 Objectives (cont.) Knowledge In general terms, describe the use of master pages, content pages, content placeholders, master page events, and nested master pages. In general terms, describe the way a content page uses (1) Content elements and (2) the MasterPageFile attribute of its Page directive. Describe the procedure for converting a regular ASP.NET page to a content page. In general terms, describe the procedure for accessing master page controls from a content page. Murach’s ASP.NET 3.5/C#, C9 © 2008, Mike Murach & Associates, Inc. Slide 3 The Shopping Cart application with a master page: The master page and content page Content placeholder Murach’s ASP.NET 3.5/C#, C9 © 2008, Mike Murach & Associates, Inc. Slide 4 The Shopping Cart application with a master page: The rendered page Murach’s ASP.NET 3.5/C#, C9 © 2008, Mike Murach & Associates, Inc. Slide 5 A new master page in Design view Murach’s ASP.NET 3.5/C#, C9 © 2008, Mike Murach & Associates, Inc. Slide 6 The aspx code for a new master page <%@ Master Language="C#" AutoEventWireup="true" CodeFile="MasterPage.master.cs" Inherits="MasterPage" %> <!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>Untitled Page</title> <asp:ContentPlaceHolder id="head" runat="server"> </asp:ContentPlaceHolder> </head> <body> <form id="form1" runat="server"> <div> <asp:ContentPlaceHolder id="ContentPlaceHolder1" runat="server"> </asp:ContentPlaceHolder> </div> </form> </body> </html> Murach’s ASP.NET 3.5/C#, C9 © 2008, Mike Murach & Associates, Inc. Slide 7 Attributes of the Master page directive Attribute Language CodeFile Inherits Description Specifies the language used for any code required by the page. Specifies the name of the code-behind file. Specifies the name of the page class defined in the code-behind file. Attributes of the ContentPlaceHolder control Attribute ID Runat Murach’s ASP.NET 3.5/C#, C9 Description Specifies the name of the content placeholder. Specifies that the control is a server-side control. © 2008, Mike Murach & Associates, Inc. Slide 8 The aspx code for the Halloween Store master page <%@ Master Language="C#" AutoEventWireup="true" CodeFile="MasterPage.master.cs" Inherits="MasterPage" %> <!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>Chapter 9: Master Page</title> <style type="text/css"> .Row1Column1 { width: 140px; height: 400px; border-color: Red; background-color: Red; } Murach’s ASP.NET 3.5/C#, C9 © 2008, Mike Murach & Associates, Inc. Slide 9 The aspx code for the master page (cont.) .Row1Column2 { width: 10px; height: 400px; } .Row1Column3 { width: 540px; height: 400px; } .Row2Column1 { width: 140px; height: 25px; border-color: Red; background-color: Red; } Murach’s ASP.NET 3.5/C#, C9 © 2008, Mike Murach & Associates, Inc. Slide 10 The aspx code for the master page (cont.) .Row2Column2 { width: 10; height: 25; } .Row2Column3 { width: 540px; height: 25; } </style> <asp:ContentPlaceHolder id="head" runat="server"> </asp:ContentPlaceHolder> </head> Murach’s ASP.NET 3.5/C#, C9 © 2008, Mike Murach & Associates, Inc. Slide 11 The aspx code for the master page (cont.) <body> <form id="form1" runat="server"> <div> <asp:Image ID="Image1" runat="server" ImageUrl="~/Images/banner.jpg" /> <table cellpadding="2" cellspacing="0"> <tr> <td class="Row1Column1" valign="top"> <br /> <asp:HyperLink ID="HyperLink1" runat="server" ForeColor="White" NavigateUrl="~/Order.aspx"> Home</asp:HyperLink> <br /> <br /> <asp:HyperLink ID="HyperLink2" runat="server" ForeColor="White" NavigateUrl="~/Cart.aspx"> Your Shopping Cart</asp:HyperLink> <br /> <br /> Murach’s ASP.NET 3.5/C#, C9 © 2008, Mike Murach & Associates, Inc. Slide 12 The aspx code for the master page (cont.) <asp:HyperLink ID="HyperLink3" runat="server" ForeColor="White" NavigateUrl="~/Service.aspx"> Customer Service</asp:HyperLink> <br /> <br /> <asp:HyperLink ID="HyperLink4" runat="server" ForeColor="White" NavigateUrl="~/About.aspx"> About Us</asp:HyperLink> </td> <td class="Row1Column2"></td> <td class="Row1Column3" valign="top"> <asp:ContentPlaceHolder id="Main" runat="server"> </asp:ContentPlaceHolder> </td> </tr> Murach’s ASP.NET 3.5/C#, C9 © 2008, Mike Murach & Associates, Inc. Slide 13 The aspx code for the master page (cont.) <tr> <td class="Row2Column1"></td> <td class="Row2Column2"></td> <td class="Row2Column3"> <asp:Label ID="lblMessage" runat="server"></asp:Label> </td> </tr> </table> </div> </form> </body> </html> Murach’s ASP.NET 3.5/C#, C9 © 2008, Mike Murach & Associates, Inc. Slide 14 The code-behind file for the master page using using using using using using using using using using using using using System; System.Collections; System.Configuration; System.Data; System.Linq; System.Collections; System.Web; System.Web.Security; System.Web.UI; System.Web.UI.HtmlControls; System.Web.UI.WebControls; System.Web.UI.WebControls.WebParts; System.Xml.Linq; public partial class MasterPage : System.Web.UI.MasterPage { protected void Page_Load(object sender, EventArgs e) { int daysUntil = DaysUntilHalloween(); Murach’s ASP.NET 3.5/C#, C9 © 2008, Mike Murach & Associates, Inc. Slide 15 The code-behind file for the master page (cont.) if (daysUntil == 0) lblMessage.Text = else if (daysUntil == lblMessage.Text = else lblMessage.Text = + " days left "Happy Halloween!"; 1) "Tomorrow is Halloween!"; "There are only " + daysUntil until Halloween!"; } private int DaysUntilHalloween() { DateTime halloween = new DateTime(DateTime.Today.Year, 10, 31); if (DateTime.Today > halloween) halloween = halloween.AddYears(1); TimeSpan ts = halloween - DateTime.Today; return ts.Days; } } Murach’s ASP.NET 3.5/C#, C9 © 2008, Mike Murach & Associates, Inc. Slide 16 The aspx code for a new page that uses the master page <%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="Order.aspx.cs" Inherits="Order" Title="Untitled Page" %> <asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server"> </asp:Content> <asp:Content ID="Content2" ContentPlaceHolderID="Main" Runat="Server"> </asp:Content> Murach’s ASP.NET 3.5/C#, C9 © 2008, Mike Murach & Associates, Inc. Slide 17 Two ways to create a new content page Choose the WebsiteAdd New Item command. Then, select the Web Form template, enter the name for the form, check the Select Master Page check box, and click Add. When the Select a Master Page dialog box appears, select the master page you want and click OK. Select the master page in the Solution Explorer, then choose the WebsiteAdd Content Page command. Murach’s ASP.NET 3.5/C#, C9 © 2008, Mike Murach & Associates, Inc. Slide 18 How to convert a regular ASP.NET page to a content page First, add a MasterPageFile attribute to the Page directive that specifies the URL of the master page. Next, replace the Div element that contains the actual content of the page with a Content element like this: <asp:Content ID="Content2" ContentPlaceHolderID="Main" Runat="Server"> </asp:Content> Then, if the Head element contains other elements used by the page, such as styles, replace the Head element with a Content element like this: <asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server"> </asp:Content> Last, delete everything that’s outside the Content elements except for the Page directive. Murach’s ASP.NET 3.5/C#, C9 © 2008, Mike Murach & Associates, Inc. Slide 19 Two other ways to specify the master page In the web.config file <system.web> . <pages masterPageFile="MasterPage.master" /> . </system.web> In the Page_PreInit event handler protected void Page_PreInit(object sender, EventArgs e) { MasterPageFile = "MasterPage.master"; } Murach’s ASP.NET 3.5/C#, C9 © 2008, Mike Murach & Associates, Inc. Slide 20 A content page in Design view Murach’s ASP.NET 3.5/C#, C9 © 2008, Mike Murach & Associates, Inc. Slide 21 The aspx code for the Order content page <%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="Order.aspx.cs" Inherits="Order" %> <asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server"> <style type="text/css"> .style1 { width: 250px; } .style2 { width: 20px; } </style> </asp:Content> Murach’s ASP.NET 3.5/C#, C9 © 2008, Mike Murach & Associates, Inc. Slide 22 The aspx code for the Order content page (cont.) <asp:Content ID="Content2" ContentPlaceHolderID="Main" Runat="Server"> <br /> <asp:Label ID="Label1" runat="server" Text="Please select a product:"></asp:Label>&nbsp; <asp:DropDownList ID="ddlProducts" runat="server" DataSourceID="AccessDataSource1" DataTextField="Name" DataValueField="ProductID" Width="150px" AutoPostBack="True"> </asp:DropDownList> <asp:AccessDataSource ID="AccessDataSource1" runat="server" DataFile="~/App_Data/Halloween.mdb" SelectCommand="SELECT [ProductID], [Name], [ShortDescription], [LongDescription], [ImageFile], [UnitPrice] FROM [Products] ORDER BY [Name]"> </asp:AccessDataSource> <br /> Murach’s ASP.NET 3.5/C#, C9 © 2008, Mike Murach & Associates, Inc. Slide 23 The aspx code for the Order content page (cont.) <table> <tr> <td class="style1"> <asp:Label ID="lblName" runat="server" style="font-weight: 700; font-size: larger"> </asp:Label> </td> <td class="style2" rowspan="4"> </td> <td rowspan="4" valign="top"> <asp:Image ID="imgProduct" runat="server" Height="200px" /> </td> </tr> . . </table> . . Murach’s ASP.NET 3.5/C#, C9 © 2008, Mike Murach & Associates, Inc. Slide 24 The aspx code for the Order content page (cont.) <asp:Button ID="btnAdd" runat="server" Text="Add to Cart" OnClick="btnAdd_Click" />&nbsp; <asp:Button ID="Button1" runat="server" CausesValidation="False" PostBackUrl="~/Cart.aspx" Text="Go to Cart" /> </asp:Content> Murach’s ASP.NET 3.5/C#, C9 © 2008, Mike Murach & Associates, Inc. Slide 25 Nested master pages: The aspx code for a new child master page <%@ Master Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="ChildMasterPage.master.cs" Inherits="ChildMasterPage" %> <asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server"> </asp:Content> <asp:Content ID="Content2" ContentPlaceHolderID="Main" Runat="Server"> </asp:Content> Murach’s ASP.NET 3.5/C#, C9 © 2008, Mike Murach & Associates, Inc. Slide 26 Nested master pages: The aspx code after content is added to the page <%@ Master Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="ChildMasterPage.master.cs" Inherits="ChildMasterPage" %> <asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server"> <style type="text/css"> .Row1 {width: 540px; height: 425px;} .Row2 {width: 540px; height: 25;} </style> <asp:ContentPlaceHolder ID="head" runat="server"> </asp:ContentPlaceHolder> </asp:Content> Murach’s ASP.NET 3.5/C#, C9 © 2008, Mike Murach & Associates, Inc. Slide 27 The aspx code after content is added (cont.) <asp:Content ID="Content2" ContentPlaceHolderID="Main" Runat="Server"> <table cellpadding="2" cellspacing="0"> <tr class="Row1"> <td valign="top"> <asp:ContentPlaceHolder ID="Main" runat="server"> </asp:ContentPlaceHolder> </td> </tr> <tr class="Row2"> <td> <asp:Label ID="lblMessage" runat="server"></asp:Label> </td> </tr> </table> </asp:Content> Murach’s ASP.NET 3.5/C#, C9 © 2008, Mike Murach & Associates, Inc. Slide 28 The code-behind file for a master page that provides a public property using using using using using using using using using using using using System; System.Collections; System.Configuration; System.Data; System.Linq; System.Web; System.Web.Security; System.Web.UI; System.Web.UI.HtmlControls; System.Web.UI.WebControls; System.Web.UI.WebControls.WebParts; System.Xml.Linq; Murach’s ASP.NET 3.5/C#, C9 © 2008, Mike Murach & Associates, Inc. Slide 29 The code-behind file for a master page (cont.) public partial class MasterPage : System.Web.UI.MasterPage { public Label MessageLabel { get { return lblMessage; } set { lblMessage = value; } } Murach’s ASP.NET 3.5/C#, C9 © 2008, Mike Murach & Associates, Inc. Slide 30 The code-behind file for a master page (cont.) protected void Page_Load(object sender, EventArgs e) { if (lblMessage.Text == "") { int daysUntil = DaysUntilHalloween(); if (daysUntil == 0) lblMessage.Text = "Happy Halloween!"; else if (daysUntil == 1) lblMessage.Text = "Tomorrow is Halloween!"; else lblMessage.Text = "There are only " + daysUntil + " days left until Halloween!"; } } Murach’s ASP.NET 3.5/C#, C9 © 2008, Mike Murach & Associates, Inc. Slide 31 The code-behind file for a master page (cont.) private int DaysUntilHalloween() { DateTime halloween = new DateTime(DateTime.Today.Year, 10, 31); if (DateTime.Today > halloween) halloween = halloween.AddYears(1); TimeSpan ts = halloween - DateTime.Today; return ts.Days; } } Murach’s ASP.NET 3.5/C#, C9 © 2008, Mike Murach & Associates, Inc. Slide 32 A portion of the Order.aspx page <%@ Page Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="Order.aspx.cs" Inherits="Order" %> <%@ MasterType TypeName="MasterPage" %> <asp:Content ID="Content1" ContentPlaceHolderID="Main" Runat="server"> . . . </asp:Content> Murach’s ASP.NET 3.5/C#, C9 © 2008, Mike Murach & Associates, Inc. Slide 33 Two methods from the code-behind file for the Order.aspx page protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { ddlProducts.DataBind(); this.DisplayCartMessage(); } selectedProduct = this.GetSelectedProduct(); lblName.Text = selectedProduct.Name; lblShortDescription.Text = selectedProduct.ShortDescription; lblLongDescription.Text = selectedProduct.LongDescription; lblUnitPrice.Text = selectedProduct.UnitPrice.ToString("c"); imgProduct.ImageUrl = "Images/Products/" + selectedProduct.ImageFile; } Murach’s ASP.NET 3.5/C#, C9 © 2008, Mike Murach & Associates, Inc. Slide 34 Two methods from the code-behind file for the Order.aspx page (continued) private void DisplayCartMessage() { SortedList cart = (SortedList)Session["Cart"]; if (cart != null) { if (cart.Count == 1) this.Master.MessageLabel.Text = "There is one item in your cart."; else if (cart.Count > 1) this.Master.MessageLabel.Text = "There are " + cart.Count + " items in your cart."; } } Murach’s ASP.NET 3.5/C#, C9 © 2008, Mike Murach & Associates, Inc. Slide 35