asp.net 母版頁使用詳解收藏(轉)
母版頁是VS2005中新引入的一個概念,它很好地實現界面設計的模塊化,並且實現實現了代碼的重用。它就像婚紗影樓中的婚紗模板,同一個婚紗模板可以給不同的新人用,只要把他們的照片貼在已有的婚紗模板就可以形成一張漂亮的婚紗照片,這樣可以大大簡化婚紗藝術照的設計複雜度。這裏的母版頁就像婚紗模板,而內容頁面就像兩位新人的照片。
在VS2003中沒有母版頁,要實現這種設計重用的效果,我們只能用“用戶控件”來實現,但用戶控件沒有一種可視化的組合外觀,使用起來不太方便。
母版頁(擴展名是.master)
它的使用跟普通的頁面一樣,可以可視化的設計,也可以編寫後置代碼。與普通頁面不一樣的是,它可以包含ContentPlaceHolder控件,ContentPlaceHolder控件就是可以顯示內容頁面的區域。
代碼如下:
<%@ 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事件。
使用母版頁的優點:
(1)有利於站點修改和維護,降低開發人員的工作強度
(2)有利於實現頁面佈局
(3)提供一種便於利用的對象模型