ASP.NET 2.0 中增加了內建的 MasterPage 的支持,這對我們來說是一個很大的便利。然而經過一段時間的使用,我發現 MasterPage 並不是那麼完美:嵌套的 MasterPage 不能支持設計時界面,以及下面要提到的Content Page 中增加 CSS 的問題。
通常,在沒有 2.0 之前,我們在頁面裡要增加一個 CSS 引用的語法如下:
<link rel="stylesheet" href="css/test.css" />
原本是很平常的做法。但是在一個 MasterPage 的子頁面中,出現了一個很尴尬的局面,就是:我們該把上述代碼放到什麼位置?
因為 MasterPage 的具體內容頁面中,只能定義一個個的 <asp:Content /> 標簽的內容。我們按照通常的做法在 aspx 裡面無法對頁面的 <header/> 內容進行控制。而這個 <link/> 標簽又必須放在 <header/> 內。我試驗過在 <asp:Content /> 內部加入這行代碼,但是會提示出錯的。
同時,我們也無法在 MasterPage 的 <header/> 內部放好一個 ContentPlaceHolder 用於將來放入 CSS 的引用代碼。
因此我的做法是定義了一個 helper 類如下:
static public class ControlHelper
{
static public void AddStyleSheet(Page page, string cssPath)
{
HtmlLink link = new HtmlLink();
link.Href = cssPath;
link.Attributes["rel"] = "stylesheet";
link.Attributes["type"] = "text/css";
page.Header.Controls.Add(link);
}
}
這樣,在具體頁面,我們就可以通過如下代碼添加 CSS 引用:
protected void Page_Load(object sender, EventArgs e)
{
ControlHelper.AddStyleSheet(this.Page, "css/projectPage.css");
}
並且,這個代碼支持在具體內容頁面,或者一個嵌套的 Master Page 中使用。
說到這裡也許有人會問,為什麼要把 CSS 分開成這樣來加載呢?有必要嗎?我把所有頁面的 CSS 定義到幾個公共 CSS 文件裡豈不是很好?
其實,熟悉 web 標准的 HTML 制作的朋友一定知道,在比較完美的狀態下,頁面的 html 和用於表現的 CSS 應該徹底分離。而我們基於 web 標准的設計,通常是先做出一個 Master Page 中各個框架 div 的定位代碼,以及 header,footer 部分的修飾代碼。這些是每個內容頁面都要用到的,會放在一個統一的 CSS 裡面。其他的具體內容頁面,每個頁面又會有各自不同的內容的布局,修飾樣式,因此我把每個具體頁面特定的部分放在它自己的 CSS裡。這樣就形成了一個按照 Master Page 的實現層次(可嵌套),逐層合並的 CSS 模型。其好處是實現了每個 CSS 文件的職責分離,更容易理解和維護。