以程式設計方式指定主版頁面 (VB)
查看透過 PreInit 事件處理程式以程式設計方式設定內容頁面的主版頁面。
簡介
由於使用主版頁面建立全網站版面配置中的首例,所有內容頁面都透過 MasterPageFile
指示詞中的 @Page
屬性以宣告方式參考其主版頁面。 例如,下列 @Page
指示詞會將內容頁面連結至主版頁面 Site.master
:
<%@ Page Language="C#" MasterPageFile="~/Site.master"... %>
Page
命名空間中的 System.Web.UI
類別包含MasterPageFile
屬性,該屬性會傳回內容頁面主版頁面的路徑;它是 指示詞所設定的@Page
這個屬性。 這個屬性也可以用來以程式設計方式指定內容頁面的主版頁面。 如果您想要根據外部因素動態指派主版頁面,例如瀏覽頁面的使用者,此方法會很有用。
在本教學課程中,我們會將第二個主版頁面新增至網站,並動態決定要在運行時間使用的主版頁面。
步驟 1:查看頁面生命週期
每當要求抵達網頁伺服器,取得內容頁面的 ASP.NET 頁面時,ASP.NET 引擎必須將頁面的內容控件融合到主版頁面的對應 ContentPlaceHolder 控件中。 此融合會建立單一控件階層,然後可繼續進行一般頁面生命週期。
圖 1 說明此融合。 圖 1 中的步驟 1 會顯示初始內容和主版頁面控件階層。 在 PreInit 階段的尾端,頁面上的內容控件會新增至主版頁面中對應的 ContentPlaceHolders (步驟 2)。 在此融合之後,主版頁面會做為融合控件階層的根目錄。 接著,這個融合式控件階層會新增至頁面,以產生最終的控制階層 (步驟 3)。 淨結果是頁面的控制階層包含融合控件階層。
圖 01:主版頁面和內容頁面的控件階層會在 PreInit 階段期間合併在一起(單擊以檢視完整大小的影像)
步驟 2:從程式代碼設定MasterPageFile
屬性
這個融合的主版頁面部分取決於物件MasterPageFile
屬性的值Page
。 MasterPageFile
在指示詞中@Page
設定 屬性具有在初始化階段指派 屬性的凈效果Page
MasterPageFile
,這是頁面生命週期的第一個階段。 或者,我們可以以程式設計方式設定此屬性。 不過,在圖 1 中的融合發生之前,必須設定這個屬性。
在 PreInit 階段開始時, Page
對象會引發其 PreInit
事件 並呼叫其 OnPreInit
方法。 若要以程式設計方式設定主版頁面,我們可以建立 PreInit
事件的事件處理程式,或覆寫 OnPreInit
方法。 讓我們看看這兩種方法。
從開啟 Default.aspx.vb
開始,網站首頁的程序代碼後置類別檔案。 在下列程式代碼中輸入 ,以新增頁面 PreInit
事件的事件處理程式:
Protected Sub Page_PreInit(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreInit
End Sub
從這裡我們可以設定 MasterPageFile
屬性。 更新程序代碼,使其將值 “~/Site.master” 指派給 MasterPageFile
屬性。
Protected Sub Page_PreInit(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreInit
Me.MasterPageFile = "~/Site.master"
End Sub
如果您設定斷點並從偵錯開始,您會看到每當 Default.aspx
瀏覽頁面或每當有回傳至此頁面時, Page_PreInit
事件處理程式就會執行 ,並將 MasterPageFile
屬性指派給 “~/Site.master”。
或者,您可以覆寫 Page
類別的 OnPreInit
方法,並在該處設定 MasterPageFile
屬性。 在此範例中,我們不會在特定頁面中設定主版頁面,而是從 BasePage
設定主版頁面。 回想一下,我們已在主版頁面教學課程中指定標題、中繼標記和其他 HTML 標頭中,建立自定義基頁類別 (BasePage
)。 目前 BasePage
會 Page
覆寫 類別的 OnLoadComplete
方法,其中會根據網站地圖數據設定頁面 Title
的屬性。 讓我們更新 BasePage
以覆寫 OnPreInit
方法,以程序設計方式指定主版頁面。
Protected Overrides Sub OnPreInit(ByVal e As System.EventArgs)
Me.MasterPageFile = "~/Site.master"
MyBase.OnPreInit(e)
End Sub
因為我們的所有內容頁面都衍生自 BasePage
,因此所有頁面現在都會以程序設計方式指派主版頁面。 此時, 中的PreInit
Default.aspx.vb
事件處理程式是多餘的;您可以隨意將其移除。
指示詞呢@Page
?
可能有點令人困惑的是,內容頁面 MasterPageFile
的屬性現在已指定於兩個位置:以程序設計方式在 BasePage
類別的 OnPreInit
方法中,以及透過 MasterPageFile
每個內容頁面 @Page
指示詞中的屬性。
頁面生命週期中的第一個階段是初始化階段。 在這個階段中, Page
對象的 MasterPageFile
屬性會指派 MasterPageFile
指示詞中的 @Page
屬性值(如果提供的話)。 PreInit 階段會遵循初始化階段,而在這裡,我們以程式設計方式設定 Page
對象的 MasterPageFile
屬性,進而覆寫從 @Page
指示詞指派的值。 因為我們以程式設計方式設定Page
物件的 MasterPageFile
屬性,因此我們可以從 @Page
指示詞中移除 MasterPageFile
屬性,而不會影響終端用戶的體驗。 若要說服自己,請繼續從中的 @Page
Default.aspx
指示詞中移除 MasterPageFile
屬性,然後瀏覽頁面,並瀏覽瀏覽器。 如您所預期,輸出與移除屬性之前相同。
屬性是 MasterPageFile
透過指示詞設定, @Page
還是以程式設計方式設定為用戶經驗的不合時常數。 不過, MasterPageFile
在設計時間期間,Visual Studio 會使用 指示詞中的 @Page
屬性,在設計工具中產生 WYSIWYG 檢視。 如果您在 Visual Studio 中返回 Default.aspx
並瀏覽至設計工具,您會看到訊息:「主版頁面錯誤:頁面具有需要主版頁面參考但未指定任何控件」(請參閱圖 2)。
簡言之,您必須將 屬性留在 MasterPageFile
指示詞中 @Page
,才能在Visual Studio中享受豐富的設計時間體驗。
@Page指示詞的 MasterPageFile 屬性來呈現設計視圖“ />
圖 02:Visual Studio 使用 @Page
指示詞的屬性 MasterPageFile
來轉譯設計檢視(按兩下以檢視完整大小的影像)
步驟 3:建立替代主版頁面
因為內容頁面的主版頁面可以在運行時間以程序設計方式設定,所以可以根據某些外部準則動態載入特定主版頁面。 這項功能在網站版面配置需要根據使用者而有所不同的情況下很有用。 例如,部落格引擎 Web 應用程式可能會允許使用者為其部落格選擇版面配置,其中每個版面配置都與不同的主版頁面相關聯。 在運行時間,當訪客正在檢視使用者的部落格時,Web 應用程式必須判斷部落格的配置,並動態將對應的主版頁面與內容頁面產生關聯。
讓我們檢查如何根據一些外部準則,在運行時間動態載入主版頁面。 我們的網站目前只包含一個主版頁面(Site.master
)。 我們需要另一個主版頁面來說明在運行時間選擇主版頁面。 此步驟著重於建立和設定新的主版頁面。 步驟 4 會探討判斷運行時間要使用的主版頁面。
在名為 Alternate.master
的根資料夾中建立新的主版頁面。 此外,將新的樣式表單新增至名為 AlternateStyles.css
的網站。
圖 03:將另一個主版頁面和 CSS 檔案新增至網站 (按兩下以檢視完整大小的影像)
我設計了 Alternate.master
主版頁面,讓標題顯示在頁面頂端,置中和海軍背景。 我已分配左欄,並將該內容移至 ContentPlaceHolder 控件下方 MainContent
,而該控件現在會跨越頁面的整個寬度。 此外,我已取消排序的 Lessons 清單,並將它取代為上方 MainContent
的水平清單。 我也更新主版頁面所使用的字型和色彩(以及延伸模組,其內容頁面)。 圖 4 顯示 Default.aspx
使用 Alternate.master
主版頁面時。
注意
ASP.NET 包含定義 主題的能力。 主題是影像、CSS 檔案和樣式相關的 Web 控件屬性設定集合,可在運行時間套用至頁面。 如果您的網站的版面配置只在其 CSS 規則所顯示的影像中不同,則主題就是要走的路。 如果版面配置更明顯不同,例如使用不同的 Web 控件或具有完全不同的版面配置,則您必須使用不同的主版頁面。 如需主題的詳細資訊,請參閱本教學課程結尾的一節。
圖 04:我們的內容頁面現在可以使用新的外觀和風格 (按兩下以檢視完整大小的影像)
當主版和內容頁面的標記融合時,類別 MasterPage
會檢查以確保內容頁面中的每個 Content 控件都會參考主版頁面中的 ContentPlaceHolder。 如果找到參考不存在 ContentPlaceHolder 的內容控件,則會擲回例外狀況。 換句話說,指派給內容頁面的主版頁面必須針對內容頁面中的每個內容控件都有 ContentPlaceHolder。
主 Site.master
版頁面包含四個 ContentPlaceHolder 控件:
head
MainContent
QuickLoginUI
LeftColumnContent
我們網站中的部分內容頁面只包含一或兩個內容控件;其他包含每個可用 ContentPlaceHolders 的內容控件。 如果我們的新主版頁面 (Alternate.master
) 可能已指派給所有 ContentPlaceHolders Site.master
具有 Content 控件的內容頁面,則也必須 Alternate.master
包含與 Site.master
相同的 ContentPlaceHolder 控件。
若要讓您的 Alternate.master
主版頁面看起來類似我的頁面(請參閱圖 4),請先在樣式表單中 AlternateStyles.css
定義主版頁面的樣式。 將下列規則新增至 AlternateStyles.css
:
body
{
font-family: Comic Sans MS, Arial;
font-size: medium;
margin: 0px;
}
#topContent
{
text-align: center;
background-color: Navy;
color: White;
font-size: x-large;
text-decoration: none;
font-weight: bold;
padding: 10px;
height: 50px;
}
#topContent a
{
text-decoration: none;
color: White;
}
#navContent
{
font-size: small;
text-align: center;
}
#footerContent
{
padding: 10px;
font-size: 90%;
text-align: center;
border-top: solid 1px black;
}
#mainContent
{
text-align: left;
padding: 10px;
}
接下來,將下列宣告式標記新增至 Alternate.master
。 如您所見,Alternate.master
包含四個 ContentPlaceHolder 控件,其值與 中的 Site.master
ContentPlaceHolder 控件相同ID
。 此外,它包含 ScriptManager 控制件,對於使用 AJAX 架構 ASP.NET 網站中的頁面而言是必要的。
<!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 id="Head1" runat="server">
<title>Untitled Page</title>
<asp:ContentPlaceHolder id="head" runat="server">
</asp:ContentPlaceHolder>
<link href="AlternateStyles.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="MyManager" runat="server">
</asp:ScriptManager>
<div id="topContent">
<asp:HyperLink ID="lnkHome" runat="server" NavigateUrl="~/Default.aspx"
Text="Master Pages Tutorials" />
</div>
<div id="navContent">
<asp:ListView ID="LessonsList" runat="server"
DataSourceID="LessonsDataSource">
<LayoutTemplate>
<asp:PlaceHolder runat="server" ID="itemPlaceholder" />
</LayoutTemplate>
<ItemTemplate>
<asp:HyperLink runat="server" ID="lnkLesson"
NavigateUrl='<%# Eval("Url") %>'
Text='<%# Eval("Title") %>' />
</ItemTemplate>
<ItemSeparatorTemplate> | </ItemSeparatorTemplate>
</asp:ListView>
<asp:SiteMapDataSource ID="LessonsDataSource" runat="server"
ShowStartingNode="false" />
</div>
<div id="mainContent">
<asp:ContentPlaceHolder id="MainContent" runat="server">
</asp:ContentPlaceHolder>
</div>
<div id="footerContent">
<p>
<asp:Label ID="DateDisplay" runat="server"></asp:Label>
</p>
<asp:ContentPlaceHolder ID="QuickLoginUI" runat="server">
</asp:ContentPlaceHolder>
<asp:ContentPlaceHolder ID="LeftColumnContent" runat="server">
</asp:ContentPlaceHolder>
</div>
</form>
</body>
</html>
測試新的主版頁面
若要測試這個新的主版頁面, BasePage
請更新 類別的 OnPreInit
方法, MasterPageFile
讓屬性被指派值 "~/Alternate.maser"
,然後瀏覽網站。 除了兩個: ~/Admin/AddProduct.aspx
和 ~/Admin/Products.aspx
之外,每個頁面都應該沒有錯誤地運作。 將產品新增至 DetailsView ~/Admin/AddProduct.aspx
,會產生 NullReferenceException
嘗試設定主版頁面 GridMessageText
屬性的程式代碼行。 在~/Admin/Products.aspx
InvalidCastException
頁面載入時擲回 ,並顯示訊息:「無法將類型為 『ASP.alternate_master』 的物件轉換成類型 'ASP.site_master'」 。
因為程式 Site.master
代碼後置類別包含未在 中 Alternate.master
定義的公用事件、屬性和方法,因此會發生這些錯誤。 這兩個 @MasterType
頁面的標記部分具有參考主版頁面的 Site.master
指示詞。
<%@ MasterType VirtualPath="~/Site.master" %>
此外,中的 DetailsView ItemInserted
事件處理程式包含的程式代碼,會將鬆散類型Page.Master
屬性轉換成 類型的Site
~/Admin/AddProduct.aspx
物件。 指示 @MasterType
詞 (以這種方式使用)和事件處理程式中的 ItemInserted
轉換緊密結合 ~/Admin/AddProduct.aspx
和 ~/Admin/Products.aspx
頁面至 Site.master
主版頁面。
為了打破這個緊密結合,我們可以擁有 Site.master
並 Alternate.master
衍生自包含公用成員定義的通用基類。 接下來,我們可以更新 @MasterType
指示詞來參考這個通用基底類型。
建立自訂基底主版頁面類別
將新的類別檔案新增至 App_Code
名為 BaseMasterPage.vb
的資料夾,並將其衍生自 System.Web.UI.MasterPage
。 我們需要在 中定義 RefreshRecentProductsGrid
方法和 GridMessageText
屬性,但我們不能簡單地從Site.master
那裡移動它們,因為這些成員會使用主版頁面特定的 Site.master
Web 控件(RecentProducts
GridView 和 GridMessage
Label)。BaseMasterPage
我們需要做的是 BaseMasterPage
,以這樣的方式設定這些成員定義在那裡,但實際上是由 BaseMasterPage
的衍生類別 (Site.master
和 Alternate.master
) 實作。 這種繼承類型可藉由將 類別標示為 MustInherit
,並將其成員標示為 MustOverride
。 簡言之,將這些關鍵詞新增至 類別及其兩個成員會宣告 BaseMasterPage
尚未實 RefreshRecentProductsGrid
作 和 GridMessageText
,但其衍生類別將會。
我們也需要在 中BaseMasterPage
定義 事件,PricesDoubled
並藉由衍生類別提供方法來引發 事件。 .NET Framework 中用來促進此行為的模式是在基類中建立公用事件,並新增名為 OnEventName
的受保護、可覆寫的方法。 然後,衍生類別可以呼叫這個方法來引發事件,也可以覆寫它,以在引發事件之前或之後立即執行程序代碼。
更新類別 BaseMasterPage
,使其包含下列程序代碼:
Public MustInherit Class BaseMasterPage
Inherits System.Web.UI.MasterPage
Public Event PricesDoubled As EventHandler
Protected Overridable Sub OnPricesDoubled(ByVal e As EventArgs)
RaiseEvent PricesDoubled(Me, e)
End Sub
Public MustOverride Sub RefreshRecentProductsGrid()
Public MustOverride Property GridMessageText() As String
End Class
接下來,移至程式 Site.master
代碼後置類別,並讓它衍生自 BaseMasterPage
。 因為 BaseMasterPage
包含標示 MustOverride
的成員,所以我們必須在 中 Site.master
覆寫這些成員。 將 Overrides
關鍵詞新增至 方法和屬性定義。 也更新程序代碼,以呼叫基類OnPricesDoubled
的方法,在 Button Click
的事件處理程式中DoublePrice
引發 PricesDoubled
事件。
在這些修改之後,程式 Site.master
代碼後置類別應該包含下列程式代碼:
Partial Class Site
Inherits BaseMasterPage
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
DateDisplay.Text = DateTime.Now.ToString("dddd, MMMM dd")
End Sub
Public Overrides Sub RefreshRecentProductsGrid()
RecentProducts.DataBind()
End Sub
Public Overrides Property GridMessageText() As String
Get
Return GridMessage.Text
End Get
Set(ByVal Value As String)
GridMessage.Text = Value
End Set
End Property
Protected Sub DoublePrice_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles DoublePrice.Click
' Double the prices
DoublePricesDataSource.Update()
' Refresh RecentProducts
RecentProducts.DataBind()
' Raise the PricesDoubled event
MyBase.OnPricesDoubled(EventArgs.Empty)
End Sub
End Class
我們也需要更新 Alternate.master
的程式代碼後置類別,以衍生自 BaseMasterPage
並覆寫這兩 MustOverride
個成員。 但是,因為 Alternate.master
不包含列出最新產品的 GridView,也不包含在將新產品新增至資料庫之後顯示訊息的 Label,因此這些方法不需要執行任何動作。
Partial Class Alternate
Inherits BaseMasterPage
Public Overrides Property GridMessageText() As String
Get
Return String.Empty
End Get
Set(ByVal value As String)
' Do nothing
End Set
End Property
Public Overrides Sub RefreshRecentProductsGrid()
' Do nothing
End Sub
End Class
參考基底主版頁面類別
既然我們已經完成 類別, BaseMasterPage
並擴充了兩個主版頁面,最後一個步驟是更新 ~/Admin/AddProduct.aspx
和 ~/Admin/Products.aspx
頁面,以參考此一般類型。 從變更這兩個頁面中的 @MasterType
指示詞開始:
<%@ MasterType VirtualPath="~/Site.master" %>
變更為:
<%@ MasterType TypeName="BaseMasterPage" %>
屬性現在參考基底類型 (BaseMasterPage
) 而不是參考檔案路徑@MasterType
。 因此,這兩個頁面程序代碼後置類別中使用的強型 Master
別屬性現在為類型 BaseMasterPage
(而不是 類型 Site
)。 有了這項變更,請重新流覽 ~/Admin/Products.aspx
。 先前,這會導致轉型錯誤,因為頁面已設定為使用 Alternate.master
主版頁面,但 @MasterType
指示詞參考了 Site.master
檔案。 但現在頁面會轉譯而不會發生錯誤。 這是因為 Alternate.master
主版頁面可以轉換成 類型的 BaseMasterPage
物件(因為它會擴充它)。
在 中 ~/Admin/AddProduct.aspx
需要進行一個小變更。 DetailsView 控件的 ItemInserted
事件處理程式會同時使用強型 Master
別屬性和鬆散類型 Page.Master
屬性。 我們已在更新 @MasterType
指示詞時修正強型別參考,但仍需要更新鬆散型別的參考。 取代下列程式碼:
Dim myMasterPage As Site = CType(Page.Master, Site)
使用下列命令,轉換為 Page.Master
基底類型:
Dim myMasterPage As BaseMasterPage = CType(Page.Master, BaseMasterPage)
步驟 4:決定要系結至內容頁面的主版頁面
我們的 BasePage
類別目前會將所有內容頁面 MasterPageFile
的屬性設定為頁面生命週期 PreInit 階段中的硬式編碼值。 我們可以更新此程序代碼,以根據某些外部因素來建立主版頁面的基礎。 也許要載入的主版頁面取決於目前登入使用者的喜好設定。 在此情況下,我們需要在方法BasePage
中OnPreInit
撰寫程式代碼,以查閱目前瀏覽的使用者主版頁面喜好設定。
讓我們建立一個網頁,讓用戶選擇要使用的主版頁面 - Site.master
或 Alternate.master
- 並將此選項儲存在會話變數中。 首先,在名為 ChooseMasterPage.aspx
的根目錄中建立新的網頁。 建立此頁面(或任何其他內容頁面)時,您不需要系結至主版頁面,因為主版頁面是以程序設計方式在 中 BasePage
設定。 不過,如果您未將新頁面系結至主版頁面,則新頁面的預設宣告式標記會包含網頁窗體和其他主版頁面提供的內容。 您必須以適當的內容控制件手動取代此標記。 因此,我發現將新的 ASP.NET 頁面系結至主版頁面會更容易。
注意
因為 Site.master
和 Alternate.master
具有相同的 ContentPlaceHolder 控件集,所以建立新內容頁面時,您所選擇的主版頁面並不重要。 為了保持一致性,我建議使用 Site.master
。
圖 05:將新內容頁面新增至網站 (按兩下以檢視完整大小的影像)
更新 檔案 Web.sitemap
以包含本課程的專案。 在 [主版頁面] 和 [ASP.NET AJAX 課程] 底下 <siteMapNode>
新增下列標記:
<siteMapNode url="~/ChooseMasterPage.aspx" title="Choose a Master Page" />
將任何內容新增至 ChooseMasterPage.aspx
頁面之前,請花點時間更新頁面的程式代碼後置類別,使其衍生自 BasePage
(而不是 System.Web.UI.Page
)。 接下來,將DropDownList控件新增至頁面、將其 ID
屬性設定為 MasterPageChoice
,並新增兩個 ListItems,其 Text
值為 “~/Site.master” 和 “~/Alternate.master”。
將 Button Web 控制項新增至頁面,並將其 和 ID
Text
屬性分別設定為 SaveLayout
和 [儲存版面配置選擇]。 此時,頁面的宣告式標記看起來應該如下所示:
<p>
Your layout choice:
<asp:DropDownList ID="MasterPageChoice" runat="server">
<asp:ListItem>~/Site.master</asp:ListItem>
<asp:ListItem>~/Alternate.master</asp:ListItem>
</asp:DropDownList>
</p>
<p>
<asp:Button ID="SaveLayout" runat="server" Text="Save Layout Choice" />
</p>
第一次瀏覽頁面時,我們需要顯示使用者目前選取的主版頁面選擇。 建立 Page_Load
事件處理程式並新增下列程式代碼:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not Page.IsPostBack Then
If Session("MyMasterPage") IsNot Nothing Then
Dim li As ListItem = MasterPageChoice.Items.FindByText(Session("MyMasterPage").ToString())
If li IsNot Nothing Then
li.Selected = True
End If
End If
End If
End Sub
上述程式代碼只會在第一頁瀏覽時執行(而不是後續回傳)。 它會先檢查會話變數 MyMasterPage
是否存在。 如果這樣做,它會嘗試在DropDownList 中尋找相符的 MasterPageChoice
ListItem。 如果找到相符的 ListItem,屬性 Selected
會設定為 True
。
我們也需要將用戶選擇儲存至 Session 變數的程式 MyMasterPage
代碼。 建立 SaveLayout
Button Click
事件的事件處理程式,並新增下列程式代碼:
Protected Sub SaveLayout_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles SaveLayout.Click
Session("MyMasterPage") = MasterPageChoice.SelectedValue
Response.Redirect("ChooseMasterPage.aspx")
End Sub
注意
在 Click
事件處理程式在回傳時,已經選取主版頁面。 因此,直到下一頁流覽之前,使用者的下拉式清單選取才會生效。 會 Response.Redirect
強制瀏覽器重新要求 ChooseMasterPage.aspx
。
完成頁面時ChooseMasterPage.aspx
,我們的最終工作是根據 BasePage
Session 變數的值MyMasterPage
來指派 MasterPageFile
屬性。 如果未將會話變數設定為 ,則預設為 BasePage
Site.master
。
Protected Overrides Sub OnPreInit(ByVal e As System.EventArgs)
SetMasterPageFile()
MyBase.OnPreInit(e)
End Sub
Protected Overridable Sub SetMasterPageFile()
Me.MasterPageFile = GetMasterPageFileFromSession()
End Sub
Protected Function GetMasterPageFileFromSession() As String
If Session("MyMasterPage") Is Nothing Then
Return "~/Site.master"
Else
Return Session("MyMasterPage").ToString()
End If
End Function
注意
我已將對象的 屬性指派Page
MasterPageFile
出OnPreInit
事件處理程式的程式代碼,並移至兩個不同的方法。 第一個方法 SetMasterPageFile
會將 屬性指派 MasterPageFile
給第二個方法 GetMasterPageFileFromSession
所傳回的值。 我標記 SetMasterPageFile
方法 Overridable
,以便擴充的未來類別 BasePage
視需要選擇性地覆寫它以實作自定義邏輯。 我們將在下一個教學課程中看到覆寫 BasePage
的 SetMasterPageFile
屬性範例。
在此程式代碼就緒后,請瀏覽 ChooseMasterPage.aspx
頁面。 一開始,主 Site.master
版頁面已選取(請參閱圖 6),但使用者可以從下拉式清單中挑選不同的主版頁面。
圖 06:使用 Site.master
主版頁面顯示內容頁面 (按兩下以檢視完整大小的影像)
圖 07:現在使用主版頁面顯示 Alternate.master
內容頁面 (按兩下以檢視完整大小的影像)
摘要
瀏覽內容頁面時,其 [內容] 控件會與其主版頁面的 ContentPlaceHolder 控件融合在一起。 內容頁面的主版頁面是由 類別的 屬性表示Page
,該屬性會在初始化階段指派給@Page
指示詞的屬性MasterPageFile
。MasterPageFile
如本教學課程所示,只要我們在 PreInit 階段結尾之前執行此動作,就可以將值指派給 MasterPageFile
屬性。 能夠以程式設計方式指定主版頁面開啟更進階案例的大門,例如根據外部因素動態將內容頁面系結至主版頁面。
快樂程式!
深入閱讀
有關本教學課程中討論的主題的更多資訊,請參閱以下資源:
關於作者
斯科特·米切爾,多個 ASP/ASP.NET 書籍的作者,4GuysFromRolla.com 的創始人,自1998年以來一直與Microsoft Web 技術合作。 Scott 擔任獨立顧問、講師和作家。 他的最新書是 山姆斯在24小時內 ASP.NET 3.5。 斯科特可以透過 mitchell@4GuysFromRolla.com 他在的部落格聯繫到或通過他的博客 http://ScottOnWriting.NET。
特別感謝
本教學課程系列已經過許多熱心的檢閱者檢閱。 本教學課程的主要檢閱者是 Suchi Banerjee。 有興趣檢閱我即將推出的 MSDN 文章嗎? 如果是,請將一行放在 mitchell@4GuysFromRolla.com