Paul Wilson
ASP.NET 領域內的 Microsoft 最有價值專家
2003 年 10 月
適用於:
Microsoft ASP.NET Whidbey
Microsoft Visual Basic .NET
摘要:瞭解主版頁面特性,這是即將面世的 ASP.NET 版本中出現的一種靈活的頁面模板系統,可提供卓越的視覺化設計工具支援,其代號為 "Whidbey"(根據即將面世的 Microsoft Visual Studio .NET 發布版的代號命名)。(10 頁列印頁)
下載 ASP.NET Pro 樣本。
內容
本頁內容
|
多地區和 Header 標記 |
|
嵌套和動態母片 |
|
主版頁面的優點 |
注 相應的軟體產品正式發行之前,本文檔已經撰寫完畢,因此我們不能保證本文檔內所涉及的任何細節與最終交付的產品完全一致。文中的描述資訊針對本文發表時的產品,僅供在規劃時參考之用。如有更改,恕不另行通知。
大多數 Web 網站的所有頁面共用一種布局,但是傳統的 ASP 和 ASP.NET 都未曾包括對頁面模板的自動支援。並且,雖然傳統 ASP 中通常都使用包含檔案,而 ASP.NET 中經常使用使用者控制項和基本 Page 類,但是這些方法都不是內建的,且不具備設計器支援。通過加入一種名為主版頁面的靈活頁面模板系統,Microsoft ASP.NET Whidbey 改變了這種狀況。這種模板系統應該足夠簡單以便設計人員使用,同時其功能又足夠強大以供開發人員使用。
要學習這種新的主版頁面方法,最簡單的途徑就是考察一些樣本,因此,本文的剩餘部分將給你講述若干樣本,從最簡單的情況開始,逐步擴充到更進階的情況。
第一個樣本建立一個帶有網站標題、左側和右側邊欄、網站腳註和單個內容“地區”的母片,以此說明主版頁面的各種新概念和文法。首先,建立一個主版頁面作為公用布局。主版頁面與使用者控制項非常相似,不同之處在於它具有新的 master 副檔名以及一個 Master 指令。與大多數使用者控制項不同,主版頁面將包含通常位於每個獨立頁面中的頂級 HTML 標籤,例如 <html>、 <head>、 <body> 和 <form>。只需用普通的 HTML 標籤和伺服器控制項(在這種情況下,包括一個用於定義標題和腳註的表格,以及另一個用於定義左側和右側邊欄的內嵌表格),建立公用布局(參閱圖 1)即可。在實際頁面中將被替換掉的內容地區隨後由新的 ContentPlaceHolder 控制項進行標記,並將在實際頁面中匹配此處分配給該控制項的 ID。此 ContentPlaceHolder 控制項中所包含的任何內容就成為預設內容(僅當實際頁面沒有覆蓋此預設內容的匹配內容地區時,才會呈現此預設內容)。
程式碼範例 1. 此 IntroLayout.master 檔案是主版頁面,用於定義其他頁面的公用布局。其中包括標題、左側和右側邊欄,腳註和單個內容地區。
<%@ master language="VB" %> <html> <head> <title>Master Pages</title> <link rel="stylesheet" type="text/css" href="StyleSheet.css" /> </head> <body> <form runat="server"> <table width="100%" cellpadding="0" cellspacing="0"> <tr class="head"> <td height="25">Site Header Goes Here</td></tr> <tr><td> <table width="100%" cellpadding="5" cellspacing="0"> <tr valign="top" height="400"> <td width="200" class="left"> Site Left SideBar Goes Here</td> <td> <h1 align="center">Master Pages</h1> <asp:contentplaceholder id="Main" runat="Server"> This is Default Content -- Override on Page </asp:contentplaceholder></td> <td width="200" class="right"> Site Right SideBar Goes Here</td> </tr> </table> </td></tr> <tr class="foot"> <td height="25">Site Footer Goes Here</td></tr> </table> </form> </body> </html>
最後,為頁面所特有的內容建立一個內容頁面,其中 Page 指令中使用了新的 Master 屬性以便連結主版頁面。除了一個可選的伺服器指令碼塊之外,唯一允許使用的頂級元素就是新的 Content 控制項,這種控制項替換匹配的 ContentPlaceHolder 控制項(在主版頁面中定義)。Content 控制項具有一個 ContentPlaceHolderID 屬性,這個屬性必須與它要覆蓋的 ContentPlaceHolder 控制項原先被指定的 ID 相匹配。否則,該內容地區中頁面所特有的內容包括普通 HTML 標籤和伺服器控制項,包括頁面或控制項事件處理常式。請注意,通過包含一個帶有 Master 屬性的 <pages> 元素,我們可以在 web.config 檔案中指定一個預設的母片,但在設計器中當前尚不支援這一功能。
程式碼範例 2. 此 IntroContent.aspx 檔案為使用了 IntroLayout.master 主版頁面的內容頁面。其中僅包含與該主版頁面中所定義的地區相對應的頁面特有內容。
<%@ page language="VB" master="~/IntroLayout.master" %> <script runat="server" language="vb"> Sub Submit_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Result.Text = TestValue.Text End Sub </script> <asp:content id="Main" runat="server" contentplaceholderid="Main"> <div align="center"> <h3>Introduction to Master Pages</h3> This is Page Content Overridden from Master<p /> <asp:textbox id="TestValue" runat="server" /><p /> <asp:button id="Submit" runat="server" text="Submit" onclick="Submit_Click" /><p /> Result: <asp:literal id="Result" runat="server" /> </div> </asp:content>
我們當然可以僅使用 SDK 完全在記事本中編寫本樣本,但當使用像 "Whidbey" 版本的 Microsoft Visual Studio .NET 這樣的 IDE 時,主版頁面的價值才真正體現出來。圖 1 顯示了當使用此主版頁面時該內容頁面的設計時視圖,從而在設計時顯示整個頁面如何進行視覺呈現。其中顯示了主版頁面本身,但該主版頁面是灰色的,因為它本身是不可編輯的,而內容頁面則是完全可設計的,其周圍帶有全新的設計工作面板。與先前版本的 Visual Studio .NET 中所使用的所有頁面模板方法不同,此處完全具有所有的 Microsoft IntelliSense,拖放或任何其他設計特性。
圖 1. Whidbey 版本的 Visual Studio .NET 包括對主版頁面的設計時支援。主版頁面本身顯示為灰色,而頁面特定的內容是可編輯的。
多地區和 Header 標記
接下來的樣本說明了如何在主版頁面中使用多個內容地區,並示範了如何利用自訂的公用屬性來擴充主版頁面。首先,將右側邊欄更改為一個 ContentPlaceHolder 控制項,在這種情況下為 ID Right,這樣在連結到此母片的每個頁面中,該地區也可被替換為一個 Content 控制項。這個新的地區將顯示在 Visual Studio .NET 設計器中且是完全可編輯的,就如其他內容地區一樣,並且如果在實際的頁面中這個地區未被覆蓋,則將呈現其預設內容。接下來,將 <title> 標記改為 ContentPlaceHolder 控制項的一部分,這樣就可以方便地在每個實際頁面中設定標題、樣式表連結和 metatag。請注意,此內容地區將不會顯示在設計器中,因為它位於 head 而不是 body 中,但就像普通的 head 標記一樣,可以很方便地在 HTML 源檔案中進行編輯。接下來,建立一個名為 LeftSideBar 的公用字串屬性(或在這種情況下為簡單起見,建立欄位),並為左側邊欄建立一個 Literal 控制項,將該控制項的 Text 屬性設定為此屬性母片 PreRender 事件中的值。在此簡單樣本中,本來還可以建立另一個內容地區,但重要的是要知道,對於可能遇到的更複雜的情況來說,主版頁面中自訂的公用屬性是易於建立和使用的。
程式碼範例 3. 此 MultipleRegions.master 檔案具有多個地區,其中一個地區用於標題和其他 head 標記。其中還定義了一個自訂的公用屬性,該屬性可在每個實際頁面中方便地進行設定。
<%@ master language="VB" %> <script runat="server" language="vb"> Public LeftSideBar As String _ = "Master.LeftSideBar Goes Here" Sub Page_PreRender(ByVal sender As Object, _ ByVal e As System.EventArgs) Left.Text = LeftSideBar End Sub </script> <html> <head> <asp:contentplaceholder id="Head" runat="server"> <title>Master Pages</title> </asp:contentplaceholder> <link rel="stylesheet" type="text/css" href="StyleSheet.css" /> </head> <body> <form runat="server"> <table width="100%" cellpadding="0" cellspacing="0"> <tr class="head"> <td height="25">Site Header Goes Here</td></tr> <tr><td> <table width="100%" cellpadding="5" cellspacing="0"> <tr valign="top" height="400"> <td width="200" class="left"> <asp:literal id="Left" runat="Server"> Master.LeftSideBar Goes Here </asp:literal></td> <td> <h1 align="center">Master Pages</h1> <asp:contentplaceholder id="Main" runat="Server"> This is Default Content -- Override on Page </asp:contentplaceholder></td> <td width="200" class="right"> <asp:contentplaceholder id="Right" runat="Server"> Site Right SideBar Goes Here </asp:contentplaceholder></td> </tr> </table> </td></tr> <tr class="foot"> <td height="25">Site Footer Goes Here</td></tr> </table> </form> </body> </html>
最後,更改內容頁面,適當使用匹配的 Content 控制項覆蓋新的地區,或者如果想要保持每個地區所定義的預設內容,則可不作改動。記住,對於那些用於 HTML head 內容(包括標題、樣式表連結和 metatag)的地區,必須手動地在 HTML 源檔案中進行編輯,因為設計器中僅顯示 body 地區。最後,儘管您可能需要首先儲存或重新載入該母片,也要在 Load 事件中設定該主版頁面自訂公用屬性的值(該值甚至在 IntelliSense 中也可使用)。
程式碼範例 4. 此 MultipleRegions.aspx 檔案為使用了 MultipleRegions.master 主版頁面的內容頁面。其中包括多個地區(包括 HTML head 中的一個地區)並使用一個自訂的屬性。
<%@ page language="VB" master="~/MultipleRegions.master" %> <script runat="server" language="vb"> Sub Page_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) Master.LeftSideBar = "Page-Specific Left SideBar" End Sub Sub Submit_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Result.Text = TestValue.Text End Sub </script> <asp:content id="Head" runat="server" contentplaceholderid="Head"> <title>Master Pages: Multiple and Head Regions</title> </asp:content> <asp:content id="Main" runat="server" contentplaceholderid="Main"> <div align="center"> <h3>Multiple and Head Regions</h3> This is Page Content Overridden from Master<p /> <asp:textbox id="TestValue" runat="server" /><p /> <asp:button id="Submit" runat="server" text="Submit" onclick="Submit_Click" /><p /> Result: <asp:literal id="Result" runat="server" /> </div> </asp:content> <asp:content id="Right" runat="server" contentplaceholderid="Right"> Page-Specific Right SideBar </asp:content>
返回頁首
嵌套和動態母片
最後一個樣本說明嵌套主版頁面的使用,並示範如何啟用在運行時根據使用者輸入而確定的動態主版頁面。請注意,至少對本測試版本而言,設計器中不支援嵌套的母片,且並不正式推薦在此測試版本中實現動態母片所需的方法,因為在後續的版本中應該提供更好的正式支援的方法。首先,建立一個如前所述的僅帶網站標題、網站腳註和單個子內容地區以及一個HTML head 地區的父級母片。
接下來,建立一個子級母片以替換該子領域,該子級母片的左側邊欄公開為一個自訂屬性,右側邊欄公開為一個內容地區,中央地區公開為主內容地區。此外,還必須利用另一個內容地區覆蓋並替換 HTML head 地區,以便對實際的頁面公開該地區,至少對當前的測試版本而言必須如此(參見附帶的代碼下載)。
最後,更改內容頁面以便連結到此子級母片,並如前所述覆蓋內容地區。接下來,在頁面指令中添加一個“裝置篩選條件”母片,在這種情況下,該母片將被命名為 "alternate"。然後,重寫 TestDeviceFilter 方法並在此 alternate 母片的條件滿足時返回 True。在這種情況下,當存在回傳時就使用 alternate 母片,儘管必須使用 Form 集合來確定這種情況(因為在此頁面生存周期的早期階段,IsPostBack 尚不可用)。最後,在 Load 事件中設定該主版頁面的自訂公用屬性值,儘管這將需要該母片的類型強制轉換(因為母片現在是動態)。此外還要注意,並不正式推薦這種方法,但這是在測試版本中實現動態母片的唯一途徑,這一方法尚在討論之中且很可能在最終發布之前變更以更好地支援動態母片。
程式碼範例 5. 此 NestedLayouts.aspx 檔案為使用了嵌套 ChildLayout.master 主版頁面的內容頁面。當頁面是回傳時,其中還動態地使用了 MultipleRegions.master。
<%@ page language="VB" master="~/ChildLayout.master" alternate:master="~/MultipleRegions.master" %> <script runat="server" language="vb"> Overrides Function TestDeviceFilter( _ ByVal deviceFilterName As String) As Boolean If deviceFilterName.Equals("alternate") Then If Request.Form.Count > 0 Then Return True End If End If Return MyBase.TestDeviceFilter(deviceFilterName) End Function Sub Page_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) If TypeOf Master Is ASP.ChildLayout_master Then CType(Master, ASP.ChildLayout_master) _ .LeftSideBar = "Nested Layouts Left SideBar" ElseIf TypeOf Master Is ASP.MultipleRegions_master Then CType(Master, ASP.MultipleRegions_master) _ .LeftSideBar = "Multiple Regions Left SideBar" End If End Sub Sub Submit_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Result.Text = TestValue.Text End Sub </script> <asp:content id="Head" runat="server" contentplaceholderid="Head"> <title>Master Pages: Nested and Dynamic Masters</title> </asp:content> <asp:content id="Main" runat="server" contentplaceholderid="Main"> <div align="center"> <h3>Nested and Dynamic Masters</h3> This is Page Content Overridden from Master<p /> <asp:textbox id="TestValue" runat="server" /><p /> <asp:button id="Submit" runat="server" text="Submit" onclick="Submit_Click" /><p /> Result: <asp:literal id="Result" runat="server" /> </div> </asp:content> <asp:content id="Right" runat="server" contentplaceholderid="Right"> Page-Specific Right SideBar </asp:content> 返回頁首
主版頁面的優點
主版頁面系統易於供設計人員使用,因為它基於 ASP.NET 的熟悉的使用者控制項模型。儘管最終加入了近乎完整的可視化,卻不需要編寫任何代碼。另一方面,主版頁面的功能強大,因為它們支援多地區、預設內容、嵌套模板、和裝置篩選條件(用於瀏覽器依賴性)。主版頁面也是完全編譯的,從而具有最佳效能,同時提供一種強型別編程模型(其中包括母片屬性的設計時 IntelliSense),儘管在最後發行之前可能會作一些折衷,以便更好地支援動態母片。
當然了,ASP.NET Whidbey 的正式發行版本還沒有發布。然而,有幾個版本的主版頁面能夠在版本 1.0 和 1.1 下運行,儘管這些版本理所當然地尚未內建整合到 Visual Studio 的設計器中。有關其他資訊,請參閱 ASP.NET 聯盟 Web 網站上 Paul Wilson's ASP.NET Corner 中的以下兩篇文章:MasterPages:Introduction 是關於 Microsoft 的最初樣本的,而 MasterPages:Improved Version 提供了一種自訂的版本,不會破壞現有的設計器。本文所提供的代碼下載也包含與這篇文章中幾乎完全相同的樣本,其中在版本 1.0 和 1.1 中使用了我自訂版本的主版頁面。
關於作者
Paul Wilson 是亞特蘭大的一名軟體架構師,他最近加入了 PRG-Schultz 的開發小組。他的 WilsonWebForm 控制項允許在 ASP.NET 中使用多表單和非回傳表單。他是 ASP.NET 領域內的 Microsoft 最有價值專家、Microsoft 的 ASP.NET 論壇的管理員,同時還是 Microsoft 認證解決方案開發人員、Microsoft 認證應用程式開發人員、Microsoft 認證資料庫管理員和 Microsoft 認證系統工程師。如果希望與他聯絡,可訪問他的 Web 網站,www.WilsonDotNet.com,或者寄送電子郵件至 Paul@WilsonDotNet.com。
本文最初發表於 asp.netPRO Magazine 2003 年 12 月刊。出版商授權重印。
轉入原英文頁面