Working with ASP.NET Master Pages Programmatically
You can perform a number of common tasks programmatically with master pages, including the following:
Accessing members that are defined on the master page, which can consist of public properties and methods or controls.
Attaching master pages to a content page dynamically.
A Visual Studio project with source code is available to accompany this topic: Download.
To provide access to members of the master page, the Page class exposes a Master property. To access members of a specific master page from a content page, you can create a strongly typed reference to the master page by creating a @ MasterType directive. The directive allows you to point to a specific master page. When the page creates its Master property, the property is typed to the referenced master page.
For example, you might have a master page named MasterPage.master that is the class name MasterPage_master. You might create @ Page and @ MasterType directives that look like the following:
<%@ Page masterPageFile="~/MasterPage.master"%>
<%@ MasterType virtualPath="~/MasterPage.master"%>
When you use a @ MasterType directive, such as the one in the example, you can reference members on the master page as in the following example:
The Master property of the page is already typed to MasterPage_master.
Getting the Values of Controls on the Master Page
At run time, the master page is merged with the content page, so the controls on the master page are accessible to content page code. (If the master page contains controls in a ContentPlaceHolder control, those controls are not accessible if overridden by a Content control from the content page.) The controls are not directly accessible as master-page members because they are protected. However, you can use the FindControl method to locate specific controls on the master page. If the control that you want to access is inside a ContentPlaceHolder control on the master page, you must first get a reference to the ContentPlaceHolder control, and then call its FindControl method to get a reference to the control.
The following example shows how you can get a reference to controls on the master page. One of the controls being referenced is in a ContentPlaceHolder control and the other is not.
' Gets a reference to a TextBox control inside a ContentPlaceHolder Dim mpContentPlaceHolder As ContentPlaceHolder Dim mpTextBox As TextBox mpContentPlaceHolder = _ CType(Master.FindControl("ContentPlaceHolder1"), _ ContentPlaceHolder) If Not mpContentPlaceHolder Is Nothing Then mpTextBox = CType(mpContentPlaceHolder.FindControl("TextBox1"), _ TextBox) If Not mpTextBox Is Nothing Then mpTextBox.Text = "TextBox found!" End If End If ' Gets a reference to a Label control that is not in a ' ContentPlaceHolder control Dim mpLabel As Label mpLabel = CType(Master.FindControl("masterPageLabel"), Label) If Not mpLabel Is Nothing Then Label1.Text = "Master page label = " + mpLabel.Text End If
You can access the contents of the master page's ContentPlaceHolder controls by using the FindControl method, as shown above. If the ContentPlaceHolder control has been merged with content from a Content control, the ContentPlaceHolder control will not contain its default content. Instead, it will contain the text and controls that are defined in the content page.
In addition to specifying a master page declaratively (in the @ Page directive or in the configuration file), you can attach a master page dynamically to a content page. Because the master page and content page are merged during the initialization stage of page processing, a master page must be assigned before then. Typically, you assign a master page dynamically during the PreInit stage, as in the following example:
Sub Page_PreInit(ByVal sender As Object, ByVal e As EventArgs) _ Handles Me.PreInit Me.MasterPageFile = "~/NewMaster.master" End Sub
Strong Typing for Dynamic Master Pages
If the content page assigns a strong type to the master page by using a @ MasterType directive, the type must apply to any master page that you assign dynamically. If you intend to select a master page dynamically, it is recommended that you create a base class from which your master pages derive. The base master-page class can then define the properties and methods that the master pages have in common. In the content page, when you assign a strong type to the master page by using a @ MasterType directive, you can assign it to the base class instead of to an individual master page.
The following examples show how to create a base master-page type that can be used by multiple master pages. The examples consist of a base type that is derived from the MasterPage control, two master pages that inherit from the base type, and a content page that allows users to select a master page dynamically by using a query string (?color=green). The base master type defines a property named MyTitle. One of the master pages overrides the MyTitle property, and the other one does not. The content page displays the MyTitle property as the page's title. The title of the page will therefore vary depending on which master page has been selected.
This is the base master-page type. It belongs in the App_Code directory.
Public Class BaseMaster Inherits MasterPage Public Overridable ReadOnly Property MyTitle() As String Get Return "BaseMaster Title" End Get End Property End Class
This is the first master page, which displays a blue background. Notice that the Inherits attribute in the @ Master directive references the base type.
<%@ Master Language="VB" Inherits="BaseMaster" ClassName="MasterBlue" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <script runat="server"> ' No property here that overrrides the MyTitle property of the base master. </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>No title</title> </head> <body> <form id="form1" runat="server"> <div style="background-color:LightBlue"> <asp:contentplaceholder id="ContentPlaceHolder1" runat="server"> Content from MasterBlue. </asp:contentplaceholder> </div> </form> </body> </html>
This is the second master page. It is the same as the first master page, except that it displays a green background, and it overrides the MyTitle property that is defined in the base type.
<%@ Master Language="VB" Inherits="BaseMaster" ClassName="MasterGreen" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <script runat="server"> Public Overrides ReadOnly Property MyTitle() As String Get Return "MasterGreen Title" End Get End Property </script> <html xmlns="http://www.w3.org/1999/xhtml" > <head runat="server"> <title>No title</title> </head> <body> <form id="form1" runat="server"> <div style="background-color:LightGreen"> <asp:contentplaceholder id="ContentPlaceHolder1" runat="server"> Content from MasterGreen. </asp:contentplaceholder> </div> </form> </body> </html>
This is the content page, which allows users to select a master page based on a query string provided with the request. The @ MasterType directive, which assigns a strong type to the page's Master property, references the base type.
<%@ Page Language="VB" Title="Content Page" MasterPageFile="~/MasterBlue.master"%> <%@ MasterType TypeName="BaseMaster" %> <script runat="server"> Protected Sub Page_PreInit(ByVal sender As Object, ByVal e As System.EventArgs) Me.MasterPageFile = "MasterBlue.master" If Request.QueryString("color") = "green" Then Me.MasterPageFile = "MasterGreen.master" End If Me.Title = Master.MyTitle End Sub </script> <asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server"> Content from Content page. </asp:Content>