Advantages of using master pages include the following:
- allow you to centralize the common functionality of your pages.
- allow you to create one controls and code and apply the results to a set of pages.
- allow you to control over the layout of the final pages
- allow you to customize the master pages from individual content pages.
主版頁面
- Master page is defined with the file extension .master 。
- Master page inherits from the MasterPage Class。
- Master page contain an @ Master directive 。
- Master pages use ContentPlaceHolder controls to defines an area for content pages。
建立 MasterPage 和 ContentPage
下面是一個主版頁面與內容頁面的範例:
Master Page
繼承 MasterPage 類別。
<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Site1.master.cs" Inherits="Practice.Site1" %> <head id="Head1" runat="server"> <title></title> <asp:ContentPlaceHolder ID="head" runat="server"> </asp:ContentPlaceHolder> </head> <body> <form id="form1" runat="server"> <div> <asp:ContentPlaceHolder ID="ContentPlaceHolder1" runat="server"> </asp:ContentPlaceHolder> </div> </form> </body>
public partial class Site1 : System.Web.UI.MasterPage { protected void Page_Load(object sender, EventArgs e) { } }
Content Page
使用 MasterPageFile 屬性,指定使用的主版頁面。
<%@ Page Language="C#" ...... MasterPageFile="Site1.Master" %> <asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server"> </asp:Content> <asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="server"> </asp:Content>
有一點要注意:若在 Master Page 的 ContentPlaceHolder 中有置放任何控制項,只要 Content Page 有指定使用該區塊,那麼在 Master Page 的控制項都會清除。 除非 Content Page 完全沒有使用該 ContentPlaceHolder ,那麼在主版頁的控制項才會出現在 Content Page。
例如,在 MasterPage 中有個選單,若 ContentPage 要使用自已的選單,就可以加入一個 <Content></Content> ,它自然就會覆蓋主版頁的選單。 若不加入 Content 控制項,就會延用主版頁的選單。
MasterPage 等級:
- 頁面等級(page level):在每個頁面繫結主版頁面。
<%@ Page Language="C#" MasterPageFile="MySite.Master" %>
- 應用程式等級(application level):設定 web.config 。
<pages masterPageFile="MySite.Master" />
- 目錄等級(folder level):設定目錄中的 web.config 。
MasterPage 事件的順序:
<span style="color:Blue">UserControl.Page_Init</span><br/> <span style="color:Orange">MasterPage.Page_Init</span><br/> Page_Init<br/> Page_InitComplete<br/> Page_Load<br/> <span style="color:Orange">MasterPage.Page_Load</span><br/> <span style="color:Blue">UserControl.Page_Load</span><br/> <span style="color:Green">Button1_Click</span><br/> Page_LoadComplete<br/> Page_PreRender<br/> <span style="color:Orange">MasterPage.Page_PreRender</span><br/> <span style="color:Green">TextBox1_PreRender</span><br/> <span style="color:Green">Button1_PreRender</span><br/> <span style="color:Blue">UserControl.Page_PreRender</span><br/> <span style="color:Blue">UserControl.TextBox1_PreRender</span><br/> <span style="color:Blue">UserControl.Button1_PreRender</span><br/> Page_PreRenderComplete<br/> </div> <p> 1.在 Load 事件之前,MasterPage 的事件會先觸發,之後則由 ContentPage 的事件先觸發。 2.在 MasterPage 中,最早的事件是 OnInit 。 </p> </div> </div> <h1 class="collapsable" onclick="displayDiv('MasterPage 與 ContentPage 的互動')">MasterPage 與 ContentPage 的互動</h1> <div id="MasterPage 與 ContentPage 的互動"> <h2 class="collapsable" onclick="displayDiv('讀取 MasterPage 中的屬性與方法')">由 ContentPage 讀取 MasterPage 中的屬性與方法</h2> <div id="讀取 MasterPage 中的屬性與方法"> <p>The basic process to reference master page properties from a content page is as follows:</p> <ol> <li> 在 <a target="_blank" href="http://msdn.microsoft.com/zh-tw/library/system.web.ui.masterpage.aspx">MasterPage</a> 中建立公開屬性.<br /> <div class="source_code"><pre class="brush:c#;" title="Master Page"> public string CompanyName { get { return (string)ViewState["CompanyName"]; } set { ViewState["CompanyName"] = value; } } protected void Page_Load(object sender, EventArgs e) { CompanyName = "vito corp."; }
<%@ Page Title="" Language="C#" MasterPageFile="~/Site1.Master" ...%> <%@ MasterType VirtualPath="~/Site1.master" %>
protected void Page_PreRender(object sender, EventArgs e) { //access Master's Property Page.Header.Title = Master.CompanyName; //invoke Master's Method Page.Header.Title = Master.GetCompanyName(); }
由 ContentPage 讀取 MasterPage 的 Controls
在內容頁,除了可以讀取主版頁的屬性之外,也可以呼叫 Master.FindControl 方法,利用控制項的名稱找出控制項。
protected void Page_PreRender(object sender, EventArgs e) { //reference Control Label Label1 = (Label)Master.FindControl("Label1"); Page.Header.Title = Label1.Text; }
由 MasterPage 讀取 ContentPage 的 Controls
叫用 ContentPlaceHolder.FindControl 以取得內容頁的控制項。
Button button1 = ContentPlaceHolder1.FindControl("btnTest") as Button; if (button1 != null) { myMessage.Show(button1.Text + " button exist"); }
由 MasterPage 叫用 ContentPage 的 Method
透過 ContentPlaceHolder 可以取得 ContentPage 中的 Page 型別,就可以叫用它的方法
ContentPage_with_MasterPage contentpage1 = ContentPlaceHolder1.Page as ContentPage_with_MasterPage; contentpage1.hello();
不過,以上做法並不好,這將使得主版頁與內容頁綁的太緊。若要執行內容中的方法,也可以引發事件,由內容頁自行訂閱處理,會是比較好的做法。
public event EventHandler TestButtonClick; protected void RaiseEvent_Click(object sender, EventArgs e) { if (TestButtonClick != null) TestButtonClick(sender, e); }
protected void Page_PreInit(object sender, EventArgs e) { // Create an event handler for the master page's TestButtonClick event Master.TestButtonClick += new EventHandler(TestButtonClick); } private void TestButtonClick(object sender, EventArgs e) { myMessage.Show("TestButtonClick inf Content Page"); }
如果想由 MasterPage 傳遞參數給 ContentPage ,也可以用這個方法。
動態改變 MasterPage
要改變 ContentPage 的主版頁,必須在 Page_PreInit 事件之前,變更 Page.MasterPageFile 屬性。
protected void Page_PreInit(object sender, EventArgs e) { if (Session["MasterPageFile"]!=null) MasterPageFile = (string)Session["MasterPageFile"]; } protected void btnMaster1_Click(object sender, EventArgs e) { Session["MasterPageFile"] = @"~/C09_Customizing_and_Personalizing/Site1.Master"; Response.Redirect(Request.Path); } protected void btnMaster2_Click(object sender, EventArgs e) { Session["MasterPageFile"] = @"~/C09_Customizing_and_Personalizing/Site2.Master"; Response.Redirect(Request.Path); }
巢狀 MasterPage
MasterPage 支援巢狀 MasterPage ,用法也沒什麼特別,但有幾點需注意:
若要找主版頁面上的控制項,就要看在那一層的主版頁面,然後用如下的語法
Master.Master.FindControl("ControlID");
若要動態變更巢狀 MasterPage 的 MasterPage ,前面有提過,必須在 Page_PreInit 事件變更,但是,因為 MasterPage 本身沒有這個事件, 所以,必須一律在 ContentPage 中,判斷 MasterPage 是否還有 MasterPage,然後用如下的語法變更。
Master.Master.MasterPageFile = "../Master2.master";
沒有留言:
張貼留言