以程式設計方式指定主版頁面 (VB)
查看透過 PreInit 事件處理程式以程式設計方式設定內容頁面的主版頁面。
簡介
由於 使用主版頁面建立 Site-Wide 版面配置中的內嵌範例,所有內容頁面都會透過 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
版頁面。 回想一下,我們已在主版頁面教學課程中建立自定義基頁類別 (BasePage
) 回 指定標題、中繼標籤和其他 HTML 標頭 教學課程。 目前 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
如果提供) ,@Page
則會將 指示MasterPageFile
詞中的 屬性值指派給 MasterPageFile
(。 PreInit 階段遵循初始化階段,而在這裏,我們會以程式設計方式設定 Page
對象的 MasterPageFile
屬性,藉此覆寫從 @Page
指示詞指派的值。 因為我們是以程式設計方式設定 Page
物件的 MasterPageFile
屬性,所以可以從指示詞中移除 MasterPageFile
屬性 @Page
,而不會影響用戶體驗。 若要確信這點,請繼續並移除 MasterPageFile
中的 Default.aspx
指示詞中的 @Page
屬性,然後瀏覽網頁瀏覽瀏覽器。 如您所預期,輸出與移除屬性之前相同。
不論屬性是 MasterPageFile
透過 @Page
指示詞設定,還是以程式設計方式設定為用戶經驗不相依。 不過,MasterPageFile
在設計時間期間,Visual Studio 會使用 指示詞中的 @Page
屬性,在 Designer 中產生 WYSIWYG 檢視。 如果您在 Visual Studio 中返回 Default.aspx
並流覽至 Designer,您會看到訊息:「主版頁面錯誤:頁面具有需要主版頁面參考的控件,但未指定任何控件」 (請參閱圖 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
,而該控件現在橫跨頁面的整個寬度。 此外,I nixed unordered Lessons 清單,並將它取代為上方 MainContent
的水平清單。 我也會更新主版頁面所使用的字型和色彩 (,並依延伸模組更新其內容頁面) 。 圖 4 顯示 Default.aspx
使用 Alternate.master
主版頁面時。
注意
ASP.NET 包括定義 主題的能力。 Theme 是影像、CSS 檔案和樣式相關 Web 控件屬性設定的集合,可在運行時間套用至頁面。 如果您的網站版面配置只在顯示的影像和其 CSS 規則中不同,則主題是要執行的方式。 如果版面配置更明顯不同,例如使用不同的 Web 控件或具有完全不同的版面配置,則您必須使用不同的主版頁面。 如需主題的詳細資訊,請參閱本教學課程結尾的一節。
圖 04:我們的內容頁面現在可以使用新的外觀和風格, (按兩下即可檢視大小完整的影像)
當主版和內容頁面的標記結合時, MasterPage
類別會檢查以確保內容頁面中的每個 Content 控件都會參考主版頁面中的 ContentPlaceHolder。 如果找到參考不存在 ContentPlaceHolder 的內容控件,就會擲回例外狀況。 換句話說,指派給內容頁面的主版頁面對於內容頁面中的每個內容控件,都必須有 ContentPlaceHolder。
主 Site.master
版頁面包含四個 ContentPlaceHolder 控件:
head
MainContent
QuickLoginUI
LeftColumnContent
網站中的部分內容頁面只包含一或兩個內容控件;其他包含每個可用 ContentPlaceHolders 的內容控件。 如果我們的新主版頁面 (Alternate.master
) 可能指派給所有 ContentPlaceHolders Site.master
的內容頁面,則其中 Alternate.master
也必須包含與 相同的 ContentPlaceHolder 控件 Site.master
。
若要讓您的 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/Products.aspx
頁面緊密結合~/Admin/AddProduct.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
BaseMasterPage
Label) 。
我們需要執行的動作是 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,也會在將新產品新增至資料庫之後顯示訊息,因此這些方法不需要執行任何動作。
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 階段中的硬式編碼值。 我們可以更新此程序代碼,以根據某些外部因素來建立主版頁面的基礎。 可能要載入的主版頁面取決於目前登入使用者的喜好設定。 在此情況下,我們需要在 OnPreInit
方法 BasePage
中撰寫程式代碼,以查閱目前瀏覽使用者的主版頁面喜好設定。
讓我們建立一個網頁,讓用戶選擇要使用的主版頁面 , 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
,並使用 “~/Site.master” 和 “~/Alternate.master” 的值新增兩個 ListItems Text
。
將 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
代碼。 建立 Button Click
事件的事件處理程式SaveLayout
,並新增下列程式代碼:
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
屬性。 如果未將 Session 變數設定為 ,則預設值為 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
主版頁面 (按兩下即可檢視完整大小的影像)
摘要
瀏覽內容頁面時,其 Content 控件會與其主版頁面的 ContentPlaceHolder 控件結合。 內容頁面的主版頁面是由 Page
類別的 MasterPageFile
屬性表示,該屬性會在初始化階段指派給 @Page
指示 MasterPageFile
詞的 屬性。 如本教學課程所示,只要我們在 PreInit 階段結束時執行此動作,就可以將值指派給 MasterPageFile
屬性。 能夠以程式設計方式指定主版頁面來開啟更進階案例的門,例如根據外部因素動態將內容頁面系結至主版頁面。
快樂的程序設計!
深入閱讀
如需本教學課程中所討論之主題的詳細資訊,請參閱下列資源:
關於作者
Scott Mitchell 是多個 ASP/ASP.NET 書籍的作者,且 4GuysFromRolla.com 的作者,自 1998 年以來,已與 Microsoft Web 技術合作。 Scott 是獨立顧問、訓練員和作者。 他的最新書籍是 Sams 在 24 小時內自行 ASP.NET 3.5。 您可以在 或 透過在 的http://ScottOnWriting.NET部落格連線mitchell@4GuysFromRolla.com到 Scott。
特別感謝
本教學課程系列是由許多實用的檢閱者檢閱。 本教學課程的首席檢閱者是 Suchi Banerjee。 有興趣檢閱即將推出的 MSDN 文章嗎? 如果是,請將一行放在我 mitchell@4GuysFromRolla.com
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應