以程式設計方式使用 ASP.NET 主版頁面
更新:2007 年 11 月
您可以用程式設計方式在主版頁面 (Master Page) 上執行一些一般工作,包括下列:
存取在主版頁面上定義的成員,這些成員可以由 public 屬性和方法或控制項組成。
以動態方式將主版頁面附加至內容頁面。
存取主版頁面上的成員
若要提供主版頁面成員的存取,Page 類別會公開 (Expose) Master 屬性 (Property)。若要從內容頁面存取特定主版頁面的成員,透過建立 @ MasterType 指示詞,即可建立對主版頁面的強型別 (Strongly Typed) 參考。指示詞可讓您指向特定的主版頁面。當頁面建立自己的 Master 屬性 (Property) 時,該屬性會成為所參考的主版頁面型別。
例如,您可能已有名為 MasterPage.master 的主版頁面,其類別名稱為 MasterPage_master。您可能建立和下面類似的 @ Page 和 @ MasterType 指示詞:
<%@ Page masterPageFile="~/MasterPage.master"%>
<%@ MasterType virtualPath="~/MasterPage.master"%>
使用 @ MasterType 指示詞時 (如範例中的指示詞),您可以參考主版頁面上的成員,如下例所示:
CompanyName.Text = Master.CompanyName
CompanyName.Text = Master.CompanyName;
頁面的 Master 屬性已經成為 MasterPage_master 的型別。
取得主版頁面上的控制項值
在執行階段時,主版頁面會與內容頁面合併,所以主版頁面上的控制項可以由內容頁面程式碼存取(如果主版頁面在 ContentPlaceHolder 控制項中包含控制項,則由 Content 控制項從內容頁面覆寫時,無法存取這些控制項)。由於這些控制項都受到保護,無法直接當做主版頁面成員存取。但是,您可以使用 FindControl 方法尋找主版頁面上特定的控制項。如果您要存取的控制項是在主版頁面上的 ContentPlaceHolder 控制項內,您必須先取得 ContentPlaceHolder 控制項的參考,然後再呼叫控制項的 FindControl 方法以取得控制項的參考。
下列範例顯示如何取得主版頁面上的控制項參考。其中一個已參考的控制項是在 ContentPlaceHolder 控制項中,其他的則不是。
' 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
// Gets a reference to a TextBox control inside a ContentPlaceHolder
ContentPlaceHolder mpContentPlaceHolder;
TextBox mpTextBox;
mpContentPlaceHolder =
(ContentPlaceHolder)Master.FindControl("ContentPlaceHolder1");
if(mpContentPlaceHolder != null)
{
mpTextBox = (TextBox) mpContentPlaceHolder.FindControl("TextBox1");
if(mpTextBox != null)
{
mpTextBox.Text = "TextBox found!";
}
}
// Gets a reference to a Label control that is not in a
// ContentPlaceHolder control
Label mpLabel = (Label) Master.FindControl("masterPageLabel");
if(mpLabel != null)
{
Label1.Text = "Master page label = " + mpLabel.Text;
}
透過使用 FindControl 方法 (如上所示),即可存取主版頁面的 ContentPlaceHolder 控制項內容。如果 ContentPlaceHolder 控制項已和 Content 控制項的內容合併,ContentPlaceHolder 控制項將不包含預設的內容。相反的,控制項會包含內容頁面中定義的文字和控制項。
以動態方式附加主版頁面
除了以宣告方式指定主版頁面 (在 @ Page 指示詞或組態檔中) 之外,您可透過動態方式將主版頁面附加至內容頁面。因為主版頁面和內容頁面會在頁面處理的初始設定階段期間合併,合併之前必須先指定主版頁面。通常來說,會在 PreInit 階段期間以動態方式指定主版頁面,如下例所示:
Sub Page_PreInit(ByVal sender As Object, ByVal e As EventArgs) _
Handles Me.PreInit
Me.MasterPageFile = "~/NewMaster.master"
End Sub
void Page_PreInit(Object sender, EventArgs e)
{ this.MasterPageFile = "~/NewMaster.master";
}
動態主版頁面的強型別
如果內容頁面使用 @ MasterType 指示詞將強型別指定給主版頁面,該型別必須套用至您以動態方式指定的任何主版頁面。如果您想要以動態方式選取主版頁面,建議您從主版頁面衍生的基底類別 (Base Class) 來建立。基底主版頁面類別接著可定義主版頁面通用的屬性和方法。在內容頁面中,當您使用 @ MasterType 指示詞將強型別指定給主版頁面時,可以將強型別指定給基底類別 (Base Class) 而非個別的主版頁面。
下列範例顯示如何建立可由多個主版頁面使用的基底主版頁面型別。這些範例是由下列項目組成:從 MasterPage 控制項衍生的基底型別 (Base Type)、從基底型別繼承的兩個主版頁面,以及可讓使用者使用查詢字串 (?color=green) 以動態方式選取主版頁面的內容頁面。基底主版型別會定義名為 MyTitle 的屬性。其中一個主版頁面會覆寫 MyTitle 屬性,其他主版頁面則不會。內容頁面會將 MyTitle 屬性當做頁面標題顯示。因此,頁面的標題會因選取的主版頁面而有所不同。
這是基底主版頁面型別。它應該放在 App_Code 目錄。
Public Class BaseMaster
Inherits MasterPage
Public Overridable ReadOnly Property MyTitle() As String
Get
Return "BaseMaster Title"
End Get
End Property
End Class
using System;
using System.Data;
using System.Configuration;
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 class BaseMaster : System.Web.UI.MasterPage
{
public virtual String MyTitle
{
get { return "BaseMaster Title"; }
}
}
這是第一個主版頁面,將顯示藍色的背景。請注意,@ Master 指示詞中的 Inherits 屬性 (Attribute) 會參考基底型別 (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 >
' No property here that overrrides the MyTitle property of the base master.
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head >
<title>No title</title>
</head>
<body>
<form id="form1" >
<div style="background-color:LightBlue">
<asp:contentplaceholder id="ContentPlaceHolder1"
>
Content from MasterBlue.
</asp:contentplaceholder>
</div>
</form>
</body>
</html>
<%@ Master Language="C#" Inherits="BaseMaster"
ClassName="MasterBlue" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<script >
// No property here that overrrides the MyTitle property of the base master.
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" >
<title>No title</title>
</head>
<body>
<form id="form1" >
<div style="background-color:LightBlue">
<asp:contentplaceholder id="ContentPlaceHolder1"
>
Content from MasterBlue.
</asp:contentplaceholder>
</div>
</form>
</body>
</html>
這是第二個主版頁面。這個頁面與第一個主版頁面相同,但它會顯示綠色背景,並且會覆寫在基底型別 (Base Type) 中定義的 MyTitle 屬性 (Property)。
<%@ 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 >
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 >
<title>No title</title>
</head>
<body>
<form id="form1" >
<div style="background-color:LightGreen">
<asp:contentplaceholder id="ContentPlaceHolder1" >
Content from MasterGreen.
</asp:contentplaceholder>
</div>
</form>
</body>
</html>
<%@ Master Language="C#" Inherits="BaseMaster"
ClassName="MasterGreen" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<script >
public override String MyTitle
{
get { return "MasterGreen Title"; }
}
</script>
<html xmlns="http://www.w3.org/1999/xhtml" >
<head id="Head1" >
<title>No title</title>
</head>
<body>
<form id="form1" >
<div style="background-color:LightGreen">
<asp:contentplaceholder id="ContentPlaceHolder1"
>
Content from MasterGreen.
</asp:contentplaceholder>
</div>
</form>
</body>
</html>
這是內容頁面,可讓使用者根據要求中所提供的查詢字串選取主版頁面。@ MasterType 指示詞 (將強型別指定給頁面的 Master 屬性) 會參考基底型別 (Base Type)。
<%@ Page Language="VB" Title="Content Page" MasterPageFile="~/MasterBlue.master"%>
<%@ MasterType TypeName="BaseMaster" %>
<script >
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>
<%@ Page Language="C#" Title="Content Page" MasterPageFile="~/MasterBlue.master"%>
<%@ MasterType TypeName="BaseMaster" %>
<script >
protected void Page_PreInit(Object sender, EventArgs e)
{
this.MasterPageFile = "MasterBlue.master";
if(Request.QueryString["color"] == "green")
{
this.MasterPageFile = "MasterGreen.master";
}
this.Title = Master.MyTitle;
}
</script>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1"
Runat="Server">
Content from Content page.
</asp:Content>