1. 程式人生 > >Asp.Net母版頁的相關知識

Asp.Net母版頁的相關知識

來自森大科技官方部落格 http://www.cnsendblog.com/index.php/?p=94

Asp.Net母版頁的相關知識
母版頁的使用與普通頁面類似,可以在其中放置檔案或者圖形、任何的HTML控制元件和Web控制元件,後置程式碼等。母版頁的副檔名以.master結尾,不能被瀏覽器直接檢視。母版頁必須在被其他頁面使用後才能進行顯示。
  它的使用跟普通的頁面一樣,可以視覺化的設計,也可以編寫後置程式碼。與普通頁面不一樣的是,它可以包含ContentPlaceHolder控制元件,ContentPlaceHolder控制元件就是可以顯示內容頁面的區域。
  母版頁僅僅是一個頁面模板,單獨的母版頁是不能被使用者所訪問的。單獨的內容頁也不能夠使用。母版頁和內容頁有著嚴格對應關係。母版頁中包含多少個ContentPlaceHolder控制元件,那麼內容頁中也必須設定與其相對應的Content控制元件。當客戶端瀏覽器向伺服器發出請求,要求瀏覽某個內容頁面時,引擎將同時執行內容頁和母版頁的程式碼,並將最終結果傳送給客戶端瀏覽器。
  母版頁具有下面的優點:
  — 使用母版頁可以集中處理頁的通用功能,以便可以只在一個位置上進行更新。
  — 使用母版頁可以方便地建立一組控制元件和程式碼,並將結果應用於一組頁。例如,可以在母版頁上使用控制元件來建立一個應用於所有頁的選單。
  — 通過允許控制佔位符控制元件的呈現方式,母版頁使您可以在細節上控制最終頁的佈局。
  — 母版頁提供一個物件模型,使用該物件模型可以從各個內容頁自定義母版頁。
  示例程式碼:
  <%@ Master Language="C#" AutoEventWireup="true" CodeFile="MasterPage.master.cs" Inherits="MasterPage" %>
  ......
  <form id="form1" runat="server">
  <div>
  <asp:contentplaceholder id="ContentPlaceHolder1" runat="server">
  </asp:contentplaceholder>
  </div>
  </form>
  ......
  注意:
  1、這裡的宣告指示符是“<%@ Master...%>”
  2、其內部包含<asp:contentplaceholder......>控制元件
  內容頁(副檔名是.aspx)
  在建立內容頁面的時候,在“新增新項”對話方塊中要選中“選擇母版頁”複選框。這樣建立的頁面就是內容頁面,內容頁面在顯示的時候會把母版面的內容一起以水印淡化的形式顯示出來,而在母版頁中的ContentPlaceHolder控制元件區域會被內容頁面中的Content控制元件替換,程式設計師可以在這裡編寫內容頁面中的內容。
  程式碼如下:
  <%@ Page Language="C#" MasterPageFile="~/MasterPage/MP.master" AutoEventWireup="true" CodeFile="Show1.aspx.cs" Inherits="MasterPage_Show1" Title="Untitled Page" %>
  <asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
  </asp:Content>
  注意:
  1、這裡的宣告指示符中多了一項MasterPageFile="~/MasterPage/MP.master",這一項是在建立內容頁面時根據“選擇母版頁”複選框的選中情況生成的。它指明瞭該頁是內容頁面,也指明瞭該內容頁面的母版頁是哪個頁面。
  2、“<asp:Content ......>”就是要在其中顯示的內容。
  一、在母版頁中編寫後臺程式碼,訪問母版頁中的控制元件:
   與普通的aspx頁面一樣,雙擊按鈕即可編寫母版頁中的程式碼
  二、在內空頁面中編寫後臺程式碼,訪問內容頁面中的控制元件:
   與普通的aspx頁面一樣,雙擊按鈕即可編寫母版頁中的程式碼
  三、在內容頁面中編寫程式碼訪問母版頁中的控制元件:
   在內容頁面中有個Master物件,它是MasterPage型別,它代表當前內容頁面的母版頁。通過這個物件的FindControl方法,我們可以找到母版面中的控制元件,這樣就可以在內容頁面中操作母版頁中的控制元件了。
  TextBox txt = (TextBox)((MasterPage)Master).FindControl("txtMaster");
  txt.Text = this.txtContent1.Text; ;
  四、在內容頁面中編寫程式碼訪問母版頁中的屬性和方法:
   仍可能通過Master物件進行訪問,只不過在這裡要把Master物件轉換成具體的母版頁型別,然後再呼叫母版頁中的屬性和方不法。
  這裡要說明的是:母版頁中要被內容頁面呼叫的屬性和方法必須是Public修改的。否則無法調到。
   假設母版頁中有下面的屬性和方法:
  public string TextValue
   {
  get
  {
  return this.txtMaster.Text;
  }
  set
  {
  this.txtMaster.Text = value;
  }
  }
  public void show(string str)
   {
  txtMaster.Text = str;
  }
  在內容頁面中可以通過下代的程式碼來實現對母版頁中方法的呼叫:
  ((MasterPage_MP)Master).show(this.txtContent1.Text);
  ((MasterPage_MP)Master).TextValue = this.txtContent1.Text;
  五、在母版頁中訪問內容頁面的控制元件:
  在母版頁中可以通過在ContentPlaceHolder控制元件中呼叫FindControl方法來取得控制元件,然後對控制元件進行操作。
  ((TextBox)this.ContentPlaceHolder1.FindControl("txtContent1")).Text = this.txtMaster.Text;
  六、在母版頁中訪問內容頁面中的方法和屬性:
   在母版頁中呼叫子頁面中的屬性和方法有點難度,因為我們無法像上一步中那樣通過FindControl來找到方法和屬性。
  於是我們想到在母版面的宣告指示符中加入下面的程式碼:
  <%@ Reference Page="~/MasterPage/Show1.aspx" %>
  在執行的時候回發現有錯誤,錯誤的內容是“無法實現迴圈引用”。這是因為預設在子頁面中引用了母版頁,你也就不能再在母版頁中引用子頁面了。
  我在網上也沒找到更好的解決方法,但這使我們想起C#是的“反射”,它可以使我們動態獲取頁面物件,並且可以呼叫它的屬性和方法。
  程式碼如下:
  Type t = this.ContentPlaceHolder1.Page.GetType();
  PropertyInfo pi = t.GetProperty("ContentValue"); //獲取ContentValue屬性
  pi.SetValue(this.ContentPlaceHolder1.Page,this.txtMaster.Text,null); //給屬性賦值
  MethodInfo mi = t.GetMethod("SetValue"); //獲取SetValue()方法
  object[] os = new object[1]; //建造輸入引數
  os[0] = txtMaster.Text;
  mi.Invoke(this.ContentPlaceHolder1.Page, os); //呼叫SetValue方法
  七、在有多個內容頁面使用母版面的情況下,在母版頁中根據不同的內容頁面實現不同的操作
   在母版頁中可以加入多個不同的內容頁面,但在設計期間,我們無法知道當前執行的是哪個內容頁面。所以只能通過分支判斷當前執行的是哪個子頁面,來執行不同的操作。這裡也用到了反射的知識。
  程式碼如下:
  string s = this.ContentPlaceHolder1.Page.GetType().ToString(); //取出內容頁面的型別名稱
  if (s == "ASP.default17_aspx") //根據不同的內容頁面型別執行不同的操作
  {
  ((TextBox)this.ContentPlaceHolder1.FindControl("TextBox2")).Text = "MastPage";
  }
  else if (s == "ASP.default18_aspx")
  {
  ((TextBox)this.ContentPlaceHolder1.FindControl("TextBox2")).Text = "Hello MastPage";
  }
  八、在母版面與內容頁面中JS程式碼的操作
  在母版頁或內容頁面中的控制元件執行之後會自動生成ID,如文字框的ID是txtContent1,在執行之後ID會自動變為ctl00_ContentPlaceHolder2_txtContent1,name屬性會變為ctl00$ContentPlaceHolder2$txtContent1。
  在JS程式碼中,我們用document.getElementById()方法,根據id取得控制元件物件的時候,應當使用ctl00_ContentPlaceHolder2_txtContent1這個ID名,否則會產生“未找到物件”的異常。
  母版頁執行機制
  母版頁僅僅是一個頁面模板,單獨的母版頁是不能被使用者所訪問的。單獨的內容頁也不能夠使用。母版頁和內容頁有著嚴格對應關係。母版頁中包含多少個ContentPlaceHolder控制元件,那麼內容頁中也必須設定與其相對應的Content控制元件。當客戶端瀏覽器向伺服器發出請求,要求瀏覽某個內容頁面時,ASP.NET引擎將同時執行內容頁和母版頁的程式碼,並將最終結果傳送給客戶端瀏覽器。
  母版頁和內容頁的執行過程可以概括為以下5個步驟。
  (1)使用者通過鍵入內容頁的URL來請求某頁。
  (2)獲取內容頁後,讀取@ Page指令。如果該指令引用一個母版頁,則也讀取該母版頁。如果是第一次請求這兩個頁,則兩個頁都要進行編譯。
  (3)母版頁合併到內容頁的控制元件樹中。
  (4)各個Content控制元件的內容合併到母版頁中相應的ContentPlaceHolder控制元件中。
  (5)呈現得到結果頁。
  母版頁和內容頁事件順序
  (1)母版頁中控制元件Init事件;
  (2)內容頁中Content控制元件Init事件;
  (3)母版頁Init事件;
  (4)內容頁Init事件;
  (5)內容頁Load事件;
  (6)母版頁Load事件;
  (7)內容頁中Content控制元件Load事件;
  (8)內容頁PreRender事件;
  (9)母版頁PreRender事件;
  (10)母版頁控制元件PreRender事件。
  (11)內容頁中Content控制元件PreRender事件。