摘要:改寫 Page 的 Render 方法,以便在網頁傳回前端之前修改其內容
今天被問到一個小問題,我想大部分以 ASP.NET 開發 Web App 的朋友都會碰到,就順便把它記在這裡。
問題很簡單:如何讓 Panel 的標題置中?
如果有指定 Panel 控制項的 GroupingText 屬性,Panel 的左上角就會顯示這個 GroupingText 屬性的值,看起來就像是 Panel 的標題。可是 Panel 沒有屬性可以讓我們控制這個標題要靠左、置中、還是靠右。
解法也很簡單:利用 Page 的 Render 事件,在網頁傳回前端瀏覽器之前,先取得要產生好的網頁內容,修改之,然後才送回前端瀏覽器。
先說明一下解問題的過程。碰到這個問題,第一個先找找看 Panel 是否已經提供相關的屬性,免得自己兜一大圈才發現元件本來就有這個功能了。若元件本身既有的功能無法解決問題,接著我會去看看網頁的 Control Tree,看看這個控制項是不是有包含什麼子控制項,可以讓我用加入 HTML 標籤的屬性的方式解決(呼叫控制項的 Attributes.Add 方法)。把 @Page 的 Trace 功能打開之後,發現 Panel 的 Control Tree 裡面還是沒有什麼線索。那只好使出最後的手段,也就是在網頁傳回瀏覽器前端之前,自行修改 ASP.NET 產生的網頁內容。
可是要修改哪裡?怎麼修改?
我們可以先利用瀏覽器的檢視原始碼功能,看一下 ASP.NET Panel 控制項會產生什麼相對應的 HTML tag。你可以看到類似下面的結果:
<div id="Panel1" style="height:82px;width:481px;"> <fieldset> <legend> 這是 Panel 的標題 </legend> </fieldset> </div>
從 HTML 內容可以看到,Panel 控制項的標題文字是由 <legend> 標籤來顯示。因此如果我們可以讓 <legend> 裡面的文字置中,就能解決我們的問題了。我們可以先用記事本編輯一個簡單的測試網頁,試著在 <legend> 標籤裡加上 align="center" 屬性,看看是不是我們想要的。例如:
<legend align="center"> ... </legend>
測試之後發現結果正是我們預期的,剩下來的問題就是如何用程式來加工最終產生的網頁內容了。
傳回前端瀏覽器的網頁內容,其實是 ASP.NET 網頁上面的所有控制項生成 (render) HTML 標籤的結果。Page 有一個 Render 方法,它的工作就是令網頁上所有子控制項產生 (render) 對應的 HTML 標籤。因此,我們只要改寫 Page 的 Render 方法,在裡面對網頁內容動點手腳就行了。程式碼很簡單,就不多解釋了,如下:
protected override void Render(HtmlTextWriter writer) { StringBuilder sb = new StringBuilder(); HtmlTextWriter myWriter = new HtmlTextWriter(new StringWriter(sb)); // 先呼叫父類別的 Render 方法,把產生的 HTML 內容寫入至我們的 sb 字串緩衝區中保存. base.Render(myWriter); // 加工 sb 的內容,把 <legend> 標籤加上置中對齊的屬性. sb.Replace("<legend>", "<legend align='center'>"); // 最後再輸出至前端瀏覽器. writer.Write(sb.ToString()); }
That's it!