ASP.NET 2.0 中的主版頁面 Master Pages
转载:http://www.yaosansi.com/blog/article.asp?id=664&page=3
適用於:
Microsoft ASP.NET 2.0
摘要:主版頁面可讓您依循一致的主題與樣式,建立 ASP.NET 頁面。Stephen Walther 告訴你如何善加利用這項新功能。
目錄
簡介
主版頁面和內容頁面
建立簡單的主版頁面
建立簡單的內容頁面
透過網站瀏覽建立主版頁面
套疊多個主版頁面
設定主版頁面
覆寫主版頁面屬性
使用頁面標題屬性
覆寫 HTML 標頭屬性
從主版頁面開放屬性和方法
動態載入主版頁面
結論
相關書籍
簡介
主版頁面是 Microsoft ASP.NET 2.0 的新功能,可讓您在 Web 應用程式的多個內容頁面中,套用相同的版面配置。主版頁面可以利用簡便的方法,建立出外觀及操作一致的網站。
多數 Web 應用程式的頁面都有一些標準項目,例如商標、瀏覽功能表以及版權聲明等。您可以在單一主版頁面上配置所有上述項目。如果您以此主版頁面為基礎來製作內容頁面,那麼所有內容頁面都會自動包含這些標準項目。
本文主要告訴您如何善加利用主版頁面,藉以建立標準版面配置。此外,我們也會進一步探討部份主版頁面的進階功能。例如,您將瞭解如何修改標頭屬性,像是內容頁面的頁面標題和中繼標記。您也將瞭解如何在 Run Time 動態載入不同的主版頁面。
主版頁面和內容頁面
現在就開始建立簡單的主版頁面。您可以使用「記事本」建立主版頁面,也可以利用 Microsoft Visual Web Developer,以完整的設計工具支援來建置主版頁面 (請參閱 [圖 1])。透過 Visual Web Developer 建立主版頁面比較有趣,而在本文中筆者並沒有假設您使用 Visual Web Developer 為工具。
圖 1. 以設計工具支援建置主版頁面
建立簡單的主版頁面
建立主版頁面的方法其實和建立一般 ASP.NET 頁面大同小異。主版頁面可以包含相同的 Web 控制項、User 控制項、HTML 內容,以及可加入標準 ASP.NET 頁面的指令碼。主版頁面和一般 ASP.NET 頁面有三大主要差異:
第一,主版頁面不像一般 ASP.NET 頁面,主版頁面的名稱必須以特殊副檔名 .master 結尾。此副檔名可將頁面標明為主版頁面。此外,ASP.NET 應用程式也經過設定,使用者無法要求副檔名為 .master 的頁面。因為直接要求主版頁面是毫無意義的做法。相反的,使用者應該從主版頁面要求內容頁面。
第二,主版頁面內含一個 <%@ Master %> 指示詞,而不含一般 <%@ Page %> 指示詞。<%@ Master %> 指示詞可支援的屬性,大多與 <%@ Page %> 指示詞相同。例如,您可利用指示詞 <%@ Master Language="vb" %> 指定頁面的程式設計語言。
主版頁面與一般 ASP.NET 頁面的最後一項差異,在於主版頁面可以不含或包含多個 ContentPlaceHolder 控制項。而 ContentPlaceHolder 控制項僅限於在主版頁面中使用。這個控制項用來標明主版頁面可由特定內容頁面覆寫的部份。
[程式碼範例 1] 中的主版頁面名為 Simple.master,其中包含一個 HTML 表格,而表格中則有兩個 ContentPlaceHolder 控制項。
程式碼範例 1. Simple.master
<%@ Master %> <html> <head> <title>Simple Master Page</title> </head> <body> <form id="form1" runat="server"> <table width="100%"> <tr> <td> <asp:ContentPlaceHolder id="ContentPlaceHolder1" runat="server" /> </td> <td> <asp:ContentPlaceHolder id="ContentPlaceHolder2" runat="server" /> </td> </tr> </table> </form> </body> </html>
[程式碼範例 1] 中的主版頁面包含兩個 ContentPlaceHolder 控制項,名稱分別為 ContentPlaceHolder1 和 ContentPlaceHolder2。這兩個控制項用來標明在主版頁面中,可因為特定內容頁面而做修改的部份。若您在 Visual Web Developer 設計工具的 [程式碼範例 1] 中開啟主版頁面,即出現 [圖 2] 的頁面。
圖 2. Simple.master 主版頁面
您會發現 [程式碼範例 1] 中的主版頁面包含標準起始 HTML 標記。例如其中就包含了 HTML <title> 和 <body> 標記。一般而言,在主版頁面中都會包含這些標準標記。本文稍後 (在〈覆寫主版頁面屬性〉一節中),將討論如何在特定內容頁面中變更標題的方法。
此外,也請注意主版頁面包含了伺服器端的 <form> 標記。既然 ASP.NET 頁面中只允許包含一個伺服器端 <form> 標記,那麼您最好將這個標記放在主版頁面中。
建立簡單的內容頁面
建立主版頁面之後,即可以該主版頁面為基礎,建立一或多個內容頁面。所謂內容頁面就是向 Web 瀏覽器要求的實際頁面。內容頁面和一般的 ASP.NET 檔案一樣,使用 .aspx 副檔名;其他部份也和一般的 ASP.NET 頁面相似,唯獨有兩大主要的差異:
第一,內容頁面中的所有內容,都必須包含在 Content 控制項之中。Content 控制項可用來將內容頁面的內容部份,對應到主版頁面的 ContentPlaceHolder 控制項所標明的內容部份。
第二,內容頁面必須和主版頁面產生關聯。您可以利用 <%@ Page %> 指示詞的某項屬性,使內容頁面與主版頁面產生關聯。此外,也可以利用 Web 組態檔來使內容頁面與主版頁面產生關聯。
舉例而言,[程式碼範例 2] 中的內容頁面包含兩個 Content 控制項,並且對應到 [程式碼範例 1] 中之主版頁面的 ContentPlaceHolder 控制項。
程式碼範例 2. Simple.aspx
<%@ Page MasterPageFile="~/Simple.master" %> <asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="server"> Content in Left Column </asp:Content> <asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder2" Runat="server"> Content in Right Column </asp:Content>
[程式碼範例 2] 中的內容頁面,其 <%@ Page %> 指示詞包含一個 MasterPageFile 屬性。此屬性即用來將 [程式碼範例1] 中的內容頁面與主版頁面產生關聯。
請注意兩個 Content 控制項的起始和結束標記之間,都包含文字。在這種情況下,Content 控制項僅包含文字。不過,在 Content 控制項中其實可以加入任何內容,包括 Web 控制項和 User 控制項。
在 Visual Web Developer 中編輯內容頁面時,就可以看到隱藏在背景的主版頁面 (請參閱 [圖 3])。Visual Web Developer 會自動加入 Content 控制項,而這些控制項會對應到主版頁面中的每一個 ContentPlaceHolder。
圖 3. 在 Visual Web Developer 中編輯內容頁面
透過網站瀏覽建立主版頁面
本文前面章節中所討論的主版頁面和內容頁面,其實是太過於簡化的範例。現實狀況中,通常會在主版頁面中加入標準瀏覽項目,例如功能表列及追蹤機制。在這一節中,我們會以更實際的角度,逐步討論建立主版頁面的程序 (請參閱 [圖 4])。
圖 4. 較複雜的主版頁面
主版頁面將同時包含 SiteMapPath 控制項和 Menu 控制項,以便瀏覽。SiteMapPath 控制項顯示追蹤機制,而 Menu 控制項則顯示瀏覽功能表。這兩個控制項都將使用 [程式碼範例 3] 中的 SiteMap 檔案。
程式碼範例 3. web.sitemap
<?xml version="1.0" encoding="utf-8" ?> <siteMap> <siteMapNode url="~/Default.aspx" title="Home"> <siteMapNode url="~/Products.aspx" title="Products"/> <siteMapNode url="~/Services.aspx" title="Services"/> </siteMapNode> </siteMap>
[程式碼範例 3] 中的 SiteMap 檔案共定義三個節點:首頁、產品頁面和服務頁面。而每個節點都有其指定的 URL 與標題屬性。[程式碼範例 4] 中的主版頁面利用這個檔案,使用 SiteMapPath 和 Menu 控制項。
程式碼範例 4. NavMaster.master
<%@ Master %> <html> <head> <title>NavMaster</title> </head> <body> <form id="form1" runat="server"> <table width="100%" border="0" cellpadding="5"> <tr> <td colspan="2"> <asp:Image id="Image1" ImageUrl="~/Logo.gif" Runat="Server" /> </td> </tr> <tr bgcolor="lightblue"> <td colspan="2"> <asp:SiteMapPath id="SiteMapPath1" Runat="Server" /> </td> </tr> </table> <table width="100%" cellpadding="10" border="0"> <tr> <td valign="top" width="100" bgcolor="#eeeeee"> <asp:Menu id="Menu" Runat="Server" DataSourceID="SiteMapDataSource1" StaticDisplayLevels="2" /> </td> <td valign="top"> <asp:contentplaceholder id="ContentColumn" runat="server" /> </td> <td valign="top" width="100" bgcolor="#eeeeee"> <asp:ContentPlaceHolder id="AdColumn" runat="server"> <asp:Image ID="Ad1" ImageUrl="Ad1.gif" Runat="Server" /> <br /> <asp:Image ID="Ad2" ImageUrl="Ad2.gif" Runat="Server" /> </asp:ContentPlaceHolder> </td> </tr> </table> <small>All contents copyright © 2004 by Microsoft Hair Stylists</small> <asp:SiteMapDataSource ID="SiteMapDataSource1" Runat="server" /> </form> </body> </html>
[程式碼範例 4] 中的主版頁面包含兩個 ContentPlaceHolder 控制項。第一個 ContentPlaceHolder 控制項用來作為主頁內容的預留位置;第二個 ContentPlaceHolder 控制項則作為廣告內容的預留位置。
第二個 ContentPlaceHolder 控制項包含預設內容,同時也包含兩個 Image 控制項,用來顯示橫幅廣告 (請參閱 [圖 5])。此預設內容可於特定內容頁面中覆寫。
圖 5. NavMaster.master 主版頁面
最後,[程式碼範例 5] 中的內容頁面是以 NavMaster.master 主版頁面為基礎 (請參閱 [圖 6])。本頁包含單一 Content 控制項,且該控制項含有主版頁面的主要內容部份的內容。
圖 6. Products.aspx 頁面
程式碼範例 5. Products.aspx
<%@ Page MasterPageFile="~/NavMaster.master" %> <asp:Content ID="Content1" ContentPlaceHolderID="ContentColumn" Runat="server"> This is the Products.aspx page </asp:Content>
套疊多個主版頁面
截至目前為止,我們已經瞭解建立單一主版頁面的方法,也知道如何以主版頁面為基礎,建立內容頁面。單一網站中可以包含多個主版頁面。例如,可以為網站中各個不同的區段,建立個別的主版頁面。
此外,如果有必要,甚至還可以套疊多個主版頁面。例如,您可為整個網站建立一個主版頁面;然後針對各個獨立區段,將其他的主版頁面套疊在網站的主版頁面之下。Visual Web Developer 不提供設計工具來支援這項作業。因此,若您需要套疊主版頁面,就必須使用來源程式碼檢視,或者透過「記事本」建置頁面。
例如,[程式碼範例 6] 中的頁面可做為網站的主版頁面。這個主版頁面包含了起始和結束 HTML 及 Form 標記,還有一個 ContentPlaceHolder 控制項。
程式碼範例 6. SiteMaster.master
<%@ Master %> <html> <head> <title>Site Master</title> </head> <body bgcolor="LightGreen"> <form id="form1" runat="server"> <h1>Site Master Page</h1> <asp:contentplaceholder id="SiteContentPlaceHolder" runat="server" /> </form> </body> </html>
[程式碼範例 7] 中的頁面即為套疊主版頁面。這個主版頁面可以覆寫網站主版頁面的內容。請注意 <%@ Master %> 指示詞是指向 SiteMaster.master 主版頁面。
程式碼範例 7. SectionMaster.master
<%@ Master MasterPageFile="~/SiteMaster.master" %> <asp:content ContentPlaceHolderID="SiteContentPlaceHolder" runat="server"> <table width="100%" bgcolor="LightYellow"> <tr> <td colspan="2"> <h1>Section Master Page</h1> </td> </tr> <tr> <td> <asp:ContentPlaceHolder id="LeftColumn" Runat="Server" /> </td> <td> <asp:ContentPlaceHolder id="RightColumn" Runat="Server" /> </td> </tr> </table> </asp:content>
最後,[程式碼範例 8] 中的內容頁面則是以區段主版頁面為基礎。請注意,本頁覆寫了區段主版頁面所包含的兩個 ContentPlaceHolder 控制項。
程式碼範例 8. NestedMasters.aspx
<%@ Page MasterPageFile="~/SectionMaster.master" %> <asp:Content ContentPlaceHolderId="LeftColumn" Runat="Server"> This content appears in the left column </asp:Content> <asp:Content ContentPlaceHolderId="RightColumn" Runat="Server"> This content appears in the right column </asp:Content>
待上述步驟完成後,即呈現出 [圖 7] 的頁面。請注意,網站主版頁面以及區段主版頁面的內容必須合併之後,才能產生最終的內容頁面。網站主版頁面的內容顯示為綠色,而區段主版頁面的內容則以黃色顯示。
圖 7. 套疊的主版頁面
設定主版頁面
與其利用 <%@ Page %> 指示詞,讓內容頁面與主版頁面產生關聯,您可以在 Web 應用程式的組態檔內,讓主版頁面與內容頁面產生關聯。使用組態檔有助於簡化大型網站的維護工作,因為只要在同一個位置,就能夠變更與諸多內容頁面相關聯的主版頁面。
您可於組態檔的 <pages> 項目中,設定主版頁面。(此項目會出現在組態檔的 <system.web> 區段中)。例如,下列 <pages> 項目可將預設的主版頁面設定為「SuperMaster.master」:
<pages masterPageFile="SuperMaster.master" />
在組態檔中指派主版頁面時,有兩件事必須特別注意:第一,設定於內容頁面中的主版頁面為首要優先,組態檔內設定的其他主版頁面則為其次。因此,若您要使用 Web.Config 檔來設定主版頁面,就不可在內容頁面中包含 MasterPageFile 屬性。
第二,在您的應用程式中,可以將多個 Web.Config 檔分別置於不同的子資料夾中,以便用來設定不同的主版頁面。換句話說,想要覆寫子資料夾中 Web.Config 檔設定的主版頁面,只要建立一個新的 Web.Config 檔即可。
覆寫主版頁面屬性
在使用主版頁面時最容易遇到的問題,就是如何為個別內容頁面中的主版頁面,覆寫如頁面標題和中繼標記等屬性。一般而言,最好是為每個內容頁面呈現出獨特的標題;就算使用同一共用的主版頁面,各個內容頁面也要獨一無二。
在特定內容頁面的主版頁面中,有許多不同的方法可以覆寫其內容。我們將於本節中陸續探討各種方法。
使用頁面標題屬性
如果您只要在內容頁面中,變更由主版頁面所呈現的頁面標題,那麼您可以利用 <%@ Page %> 指示詞的 Title 屬性來變更。此屬性只有在主版頁面使用伺服器端 HtmlHead 控制項的時候,才能發生作用。
例如,[程式碼範例 9] 中的主版頁面,包含一個伺服器端 HtmlHead 控制項。
程式碼範例 9. TitleMaster.master
<%@ Master %> <html> <head runat="server"> <title>Master Title</title> </head> <body> <form id="form1" runat="server"> <asp:contentplaceholder id="ContentPlaceHolder1" runat="server" /> </form> </body> </html>
請注意,[程式碼範例 9] 中的 <head> 標記,包含一個 runat="server" 屬性。這個屬性可將 <head> 標記轉換成伺服器端的 HtmlHead 控制項。
[程式碼範例 10] 中的內容頁面覆寫頁面標題。請注意,本頁頂端的 <%@ Page %> 指示詞已為其 Title 屬性指定值。呈現頁面時,「Content Page Title」字樣隨即顯示為頁面標題。
程式碼範例 10. TitleContent.aspx
<%@ Page MasterPageFile="~/TitleMaster.master" Title="Content Page Title" %> <asp:Content ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server"> Here is some content </asp:Content>
覆寫 HTML 標頭屬性
若您需要覆寫 HTML 標頭的其他屬性,諸如中繼標記或樣式標記等,您可以直接從內容頁面參照 HtmlHead 項目。HtmlHead 控制項實作 IPageHeader 介面,其中包括下列屬性:
- LinkedStyleSheets—連結 HTML 頁面的外部樣式表。
- Metadata—中繼資料標記的集合。
- StyleSheet—代表適用於 HTML 頁面的各種樣式。
- Title—HTML 頁面標題。
您可以在內容頁面中修改上述任一屬性。例如,[程式碼範例 11] 中的主版頁面,包含可於內容頁面中覆寫的伺服器端 HtmlHead 控制項。
程式碼範例 11. HeaderMaster.master
<%@ Master %> <html> <head runat="server"> <title>Master Title</title> </head> <body> <form id="form1" runat="server"> <asp:contentplaceholder id="ContentPlaceHolder1" runat="server" /> </form> </body> </html>
[程式碼範例 12] 中的內容頁面,可同時修改 HtmlHead 控制項的 Title 和 Metadata 屬性,以便顯示自訂內容。
程式碼範例 12. HeaderContent.aspx (Microsoft Visual Basic .NET)
<%@ Page Language="VB" MasterPageFile="~/HeaderMaster.master" %> <script runat="server"> Sub Page_Load() Master.Page.Header.Title = "Content Title" Master.Page.Header.Metadata.Add("Keywords", "blah,blah") Master.Page.Header.Metadata.Add("Description", "blah,blah") End Sub </script> <asp:Content ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server"> Here is some content </asp:Content>
程式碼範例 12. HeaderContent.aspx (c#)
<%@ Page Language="c#" MasterPageFile="~/HeaderMaster.master" %> <script runat="server"> void Page_Load() { Master.Page.Header.Title = "Content Title"; Master.Page.Header.Metadata.Add("Keywords", "blah,blah"); Master.Page.Header.Metadata.Add("Description", "blah,blah"); } </script> <asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server"> Here is some content </asp:Content>
Page 物件的 Master 屬性參照至內容頁面的主版頁面 (如有必要,也可以使用 Page.Master 來取代 Master)。Header 屬性參照至 HtmlHead 項目。[程式碼範例 12] 中的內容頁面,可修改 HtmlHead 控制項的 Title 和 Metadata 屬性。
從主版頁面開放屬性和方法
倘若您需要進一步控制主版頁面的內容,可以從主版頁面開放屬性和方法。您可於內容頁面中,修改主版頁面開放的公用屬性。亦可於內容頁面中,呼叫由主版頁面開放的公用方法。
舉例而言,假設您想要在內容頁面中修改主版頁面頁尾的內容。[程式碼範例 13] 中的主版頁面開放名為 Footer 的公用屬性。
程式碼範例 13. FooterMaster.master (Visual Basic .NET)
<%@ Master Language="VB" %> <script runat="server"> Private _footer As String Public Property Footer() As String Get Return _footer End Get Set(ByVal value As String) _footer = value End Set End Property </script> <html> <head runat="server"> <title>Footer Master</title> </head> <body> <form id="form1" runat="server"> <asp:contentplaceholder id="ContentPlaceHolder1" runat="server" /> <br /> <small><%= _footer %></small> </form> </body> </html>
程式碼範例 13. FooterMaster.master (C#)
<%@ Master Language="C#" %> <script runat="server"> private string _footer; public string Footer { get { return _footer; } set { _footer = value; } } </script> <html> <head id="Head1" runat="server"> <title>Footer Master</title> </head> <body> <form id="form1" runat="server"> <asp:contentplaceholder id="ContentPlaceHolder1" runat="server" /> <br /> <small><%= _footer %></small> </form> </body> </html>
在 [程式碼範例 13] 中,公用 Footer 屬性可修改私用欄位 named _footer。private _footer 欄位顯示於主版頁面底部,並採用內嵌運算式 <%= _footer %>。
[程式碼範例 14] 中的內容頁面可設定 Footer 屬性。Footer 屬性是由 Page 物件的 Master 屬性所開放。一般而言,Master 屬性代表一個 MasterPage 物件。不過,此內容頁面包含的 <%@ MasterType %> 指示詞會將 Master 屬性值轉換到 FooterMaster 物件上。
程式碼範例 14. FooterContent.aspx (Visual Basic .NET)
<%@ Page Language="VB" MasterPageFile="~/FooterMaster.master" %> <%@ MasterType VirtualPath="~/FooterMaster.master" %> <script runat="server"> Sub Page_Load() Master.Footer = "Custom Page Footer" End Sub </script> <asp:Content ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server"> Here is some content </asp:Content>
程式碼範例 14. FooterContent.aspx (C#)
<%@ Page Language="C#" MasterPageFile="~/FooterMaster.master" %> <%@ MasterType VirtualPath="~/FooterMaster.master" %> <script runat="server"> void Page_Load() { Master.Footer = "Custom Page Footer"; } </script> <asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server"> Here is some content </asp:Content>
只要開放主版頁面中的屬性和方法,即可修改主版頁面所呈現的各個層面。
動態載入主版頁面
在本文最後一節中,我們將討論主版頁面的進階應用方法,並檢視如何於 Run Time 動態載入不同的主版頁面。
在某些情況下,動態載入主版頁面其實很實用。首先,您的網站必須和一或多個網站合作,成為聯合品牌。若有人從合作網站連結至您的網站上,最好能自動載入符合該合作網站外觀及操作的主版頁面。
還有另一種情況,也最好能動態載入主版頁面:讓應用程式使用者能夠自行挑選一種版面配置。您可為使用者提供一套標準主版頁面。這樣一來,應用程式使用者就能藉由選取偏好的主版頁面,來選擇其偏愛的版面配置方式。
您可以為 Page 物件的 MasterPageFile 屬性指派一個值,藉以動態載入主版頁面。為此屬性所指派的值必須是有效主版頁面檔案的相關路徑。
在使用 MasterPageFile 屬性的同時,還必須注意一項重要的限制條件:只有在 Page PreInit 事件發生的同時或之前,才能為此屬性指派值。PreInit 是頁面執行生命週期中,最早發生的事件。若您嘗試於稍後事件中 (如 Page Load 事件),為此屬性指派值,則會接收到例外。此限制自然有其道理,因為不同的主版頁面會分別將不同的控制項組合載入頁面中。
[程式碼範例 15] 中的內容頁面利用 MasterPageFile 屬性,於 Run Time 動態載入不同的主版頁面。
程式碼範例 15. DynamicContent.aspx (Visual Basic .NET)
<%@ Page Language="VB" MasterPageFile="~/DynamicMaster1.master" %> <script runat="server"> Sub Page_PreInit(ByVal sender As Object, ByVal e As EventArgs) MasterPageFile = Profile.Master End Sub </script> <asp:Content ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server"> Here is the content </asp:Content>
程式碼範例 15. DynamicContent.aspx (C#)
<%@ Page Language="c#" MasterPageFile="~/DynamicMaster1.master" %> <script runat="server"> void Page_PreInit(Object sender, EventArgs e) { MasterPageFile = Profile.Master; } </script> <asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server"> Here is the content </asp:Content>
在 [程式碼範例 15] 中,主版頁面會在 PreInit 事件中動態載入。在這種情況下,主版頁面檔案的路徑是從使用者設定檔載入。您可利用設定檔,持續儲存與使用者相關聯的資訊。如此一來,就在使用者瀏覽於應用程式頁面之間的同時,也可以保留使用者所選擇的主版頁面。
為了善加利用使用者設定檔,您必須將下列組態設定,加入應用程式 Web.Config 檔的 <system.web> 區段中:
<anonymousIdentification enabled="true" /> <profile> <properties> <add name="Master" allowAnonymous="true" defaultValue="DynamicMaster1.master" /> </properties> </profile>
上述設定可建立名為 Master 的 Profile 新屬性,同時供匿名使用者及已驗證的使用者使用。
[程式碼範例 15] 中的內容頁面將於 DynamicMaster1.master 和 DynamicMaster2.master 這兩個主版頁面中,擇一載入。DynamicMaster1.master 的原始程式碼位於 [程式碼範例 16] 中,而 DynamicMaster2.master 的原始程式碼則位於 [程式碼範例 17] 中。這些主版頁面十分相似,其差異在於名稱的不同以及背景顏色的差別。
程式碼範例 16. DynamicMaster1.master (Visual Basic .NET)
<%@ Master Language="vb" %> <script runat="server"> Sub Page_Load() If Not IsPostBack Then dropMaster.SelectedValue = Profile.Master End If End Sub Sub SelectMaster(ByVal s As Object, ByVal e As EventArgs) Profile.Master = dropMaster.SelectedValue Response.Redirect(Request.Path) End Sub </script> <html> <head> <title>Dynamic Master 1</title> </head> <body bgcolor="LightYellow"> <form runat="server"> <h1>Dynamic Master 1</h1> <p> <asp:DropDownList id="dropMaster" AutoPostBack="true" OnSelectedIndexChanged="SelectMaster" ValidationGroup="Master" Runat="Server"> <asp:ListItem Text="Dynamic 1" value="DynamicMaster1.master" /> <asp:ListItem Text="Dynamic 2" value="DynamicMaster2.master" /> </asp:DropDownList> </p> <asp:contentplaceholder id="ContentPlaceHolder1" runat="server" /> </form> </body> </html>
程式碼範例 16. DynamicMaster1.master (C#)
<%@ Master Language="c#" %> <script runat="server"> void Page_Load() { if (!IsPostBack) dropMaster.SelectedValue = Profile.Master; } void SelectMaster(Object s, EventArgs e) { Profile.Master = dropMaster.SelectedValue; Response.Redirect(Request.Path); } </script> <html> <head> <title>Dynamic Master 1</title> </head> <body bgcolor="LightYellow"> <form id="Form1" runat="server"> <h1>Dynamic Master 1 CS</h1> <p> <asp:DropDownList id="dropMaster" AutoPostBack="true" OnSelectedIndexChanged="SelectMaster" ValidationGroup="Master" Runat="Server"> <asp:ListItem Text="Dynamic 1" value="DynamicMaster1.master" /> <asp:ListItem Text="Dynamic 2" value="DynamicMaster2.master" /> </asp:DropDownList> </p> <asp:contentplaceholder id="ContentPlaceHolder1" runat="server" /> </form> </body> </html>
程式碼範例 17. DynamicMaster2.master (Visual Basic .NET)
<%@ Master Language="vb" %> <script runat="server"> Sub Page_Load() If Not IsPostBack Then dropMaster.SelectedValue = Profile.Master End If End Sub Sub SelectMaster(ByVal s As Object, ByVal e As EventArgs) Profile.Master = dropMaster.SelectedValue Response.Redirect(Request.Path) End Sub </script> <html> <head> <title>Dynamic Master 2</title> </head> <body bgcolor="LightGreen"> <form id="Form1" runat="server"> <h1>Dynamic Master 2</h1> <p> <asp:DropDownList id="dropMaster" AutoPostBack="true" OnSelectedIndexChanged="SelectMaster" ValidationGroup="Master" Runat="Server"> <asp:ListItem Text="Dynamic 1" value="DynamicMaster1.master" /> <asp:ListItem Text="Dynamic 2" value="DynamicMaster2.master" /> </asp:DropDownList> </p> <asp:contentplaceholder id="ContentPlaceHolder1" runat="server" /> </form> </body> </html>
程式碼範例 17. DynamicMaster2.master (C#)
<%@ Master Language="c#" %> <script runat="server"> void Page_Load() { if (!IsPostBack) dropMaster.SelectedValue = Profile.Master; } void SelectMaster(Object s, EventArgs e) { Profile.Master = dropMaster.SelectedValue; Response.Redirect(Request.Path); } </script> <html> <head> <title>Dynamic Master 2</title> </head> <body bgcolor="LightGreen"> <form id="Form1" runat="server"> <h1>Dynamic Master 2 CS</h1> <p> <asp:DropDownList id="dropMaster" AutoPostBack="true" OnSelectedIndexChanged="SelectMaster" ValidationGroup="Master" Runat="Server"> <asp:ListItem Text="Dynamic 1" value="DynamicMaster1.master" /> <asp:ListItem Text="Dynamic 2" value="DynamicMaster2.master" /> </asp:DropDownList> </p> <asp:contentplaceholder id="ContentPlaceHolder1" runat="server" /> </form> </body> </html>
兩個主版頁面都包含 DropDownList 控制項,可以讓使用者選擇特定的主版頁面。使用者挑選某個主版頁面時,也同時呼叫 SelectMaster 方法。此方法可將選取的主版頁面指派到使用者設定檔,並且重新載入目前的頁面。此時有必要重新載入頁面,因為新選取的主版頁面必須在 PreInit 事件中載入。
結論
就個人觀點來說,主版頁面是我最偏愛的 ASP.NET 2.0 新功能。而這項新功能也將會深深影響我未來建置 ASP.NET 應用程式的方式。目前,我得手忙腳亂的處理使用者控制項 (很恐佈) 或使用自訂式 Page 類別 (超恐佈),才能建立出可以重複使用的版面配置。有了主版頁面,就能透過簡潔、直覺式的方法,建立可重複使用的版面配置。此外,其中最棒的一點就是:Microsoft Visual Studio .NET 2005 提供完整的設計工具支援,在建置頁面的同時就能直接看到頁面配置的實際效果。