MasterPage(母版頁)提供網站版面的統一範本機制,定義共用的頁首、頁尾、導覽列與 ContentPlaceHolder 佔位區域。內容頁(Content Page)僅需填入對應區塊的差異化內容,實現「寫一次版面,全站套用」的維護優勢。
<%@ Master Language="C#" AutoEventWireup="true" CodeFile="Site.master.cs" Inherits="Site" %>
<html xmlns="https://www.w3.org/1999/xhtml">
<head runat="server">
<title><asp:ContentPlaceHolder ID="head" runat="server" /></title>
<asp:ContentPlaceHolder ID="Styles" runat="server" />
</head>
<body>
<form id="form1" runat="server">
<div class="header"><!-- 共用頁首 --></div>
<div class="nav"><asp:Menu ID="MainMenu" runat="server" /></div>
<div class="main-content">
<asp:ContentPlaceHolder ID="MainContent" runat="server" />
</div>
<div class="footer"><!-- 共用頁尾 --></div>
</form>
</body>
</html>
<%@ Page Language="C#" MasterPageFile="~/Site.master" Title="首頁" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="server">
<meta name="description" content="首頁說明" />
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h1>歡迎來到首頁</h1>
<p>這裡是主要內容區域</p>
</asp:Content>
在內容頁加入 @MasterType 指令,獲得 IntelliSense 支援與型別安全:
<%@ MasterType VirtualPath="~/Site.master" %>
母版頁定義 public 方法/屬性:
public partial class Site : System.Web.UI.MasterPage {
public string PageTitle { set { lblTitle.Text = value; } }
public void ShowMessage(string msg) { lblMessage.Text = msg; }
}
內容頁呼叫:
protected void Page_Load(object sender, EventArgs e) {
Master.PageTitle = "自訂標題";
Master.ShowMessage("載入完成");
}
母版頁定義事件:
public event EventHandler<UserEventArgs> UserAction;
protected void btnLogin_Click(object sender, EventArgs e) {
UserAction?.Invoke(this, new UserEventArgs { UserName = "Admin" });
}
內容頁訂閱:
protected void Page_Init(object sender, EventArgs e) {
Master.UserAction += Master_UserAction;
}
void Master_UserAction(object sender, UserEventArgs e) {
// 處理母版頁傳來的事件
}
// 在內容頁中找母版頁控制項
Label lbl = (Label)Master.FindControl("lblTitle");
// 在母版頁中找內容頁控制項
ContentPlaceHolder cph = (ContentPlaceHolder)FindControl("MainContent");
GridView gv = (GridView)cph.FindControl("gvData");
支援多層母版頁架構,適合大型網站區域管理:
<%@ Master Language="C#" MasterPageFile="~/Site.master" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<div class="section-header"><asp:ContentPlaceHolder ID="SectionHeader" runat="server" /></div>
<div class="section-body"><asp:ContentPlaceHolder ID="SectionBody" runat="server" /></div>
</asp:Content>
protected void Page_PreInit(object sender, EventArgs e) {
if (Request.Browser.IsMobileDevice)
MasterPageFile = "~/Mobile.master";
}
string clientId = Master.FindControl("MainMenu").ClientID;
// 輸出:ctl00_MainMenu
// 母版頁
public string MetaDescription { get; set; }
public string MetaKeywords { get; set; }
// 母版頁 HTML
<meta name="description" content="<%= MetaDescription %>" />
<meta name="keywords" content="<%= MetaKeywords %>" />
// 內容頁
protected void Page_Load(object sender, EventArgs e) {
Master.MetaDescription = "產品介紹頁面";
Master.MetaKeywords = "產品,規格,價格";
}
| 問題 | 原因 | 解決 |
|---|---|---|
| 內容頁控制項 ID 衝突 | 母版頁與內容頁同名控制項 | 使用唯一命名慣例(如 mp_、cp_ 前綴) |
| JavaScript 找不到控制項 | ClientID 被命名容器修改 | 使用 ClientIDMode="Static" 或 <%= Control.ClientID %> |
| 巢狀母版頁事件不觸發 | 事件訂閱時機錯誤 | 在 Page_Init 而非 Page_Load 訂閱 |