當使用者向請求一個頁面時,伺服器端會向用戶端發送一段文本,包括可顯示標記字元和不可顯示的文本,當這段文本到達用戶端後,再通過用戶端的瀏覽器(如IE)把可視化的標記字元轉化為可視呈現給使用者,所以在使用者請求一個aspx頁面時,頁面上的Asp.net伺服器控制項,也會把文本寫入到返回的文字資料流中,在本章中我們將講述這一過程。
在Asp.net伺服器控制項提供了4個有關呈現的方法,分別是Render、RenderChildren、RenderContents和RenderControl,這4個方法都有一個HtmlTextWriter類型的參數。HtmlTextWriter的作用就是把標記字元和文本寫入倒Asp.net伺服器控制項流中,它是System.Web.UI名稱空間所有標記編寫器的基類,包括ChtmlTextWriter、Html32TextWriter和XhtmlTextWriter,這些類用於針對不同的標記類型編寫元素、屬性、樣式和布局資訊。
既然有4個有關呈現的方法,那它們的作用分別是什嗎?它們之間有什麼區別呢?我們以一個控制項的產生過程來說明:
每個頁面都有一個控制項樹,代表本頁面所擁有的所有子控制項,頁面控制項就是控制項樹的根,為了產生控制項樹,頁面將建立一個HtmlTextWriter類的執行個體,在這個執行個體中封裝了相應流,接著頁面會把HtmlTextWriter對象傳遞給RenderControl,RenderControl會檢查控制項的Visible屬性是否為真,如果是真,RenderControl會調用Render方法,而Render方法會去調用RenderContents,RenderContents方法負責將控制項的內容呈現到指定的編寫器中,如果控制項有子控制項的話,Render方法又會把HtmlTextWriter傳遞給RenderChildren方法,RenderChildren方法負責產生控制項的子控制項。
我們以一個例子來說明這個過程。
public class Class1 : WebControl
{
protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
writer.Write("RenderChildren<br>");
base.Render(writer);
}
protected override void RenderChildren(System.Web.UI.HtmlTextWriter writer)
{
writer.Write("RenderChildren<br>");
base.RenderChildren(writer);
}
public override void RenderControl(System.Web.UI.HtmlTextWriter writer)
{
writer.Write("RenderControl<br>");
base.RenderControl(writer);
}
protected override void RenderContents(System.Web.UI.HtmlTextWriter writer)
{
writer.Write("RenderContents<br>");
base.RenderContents(writer);
}
}
效果如下的圖1(RenderControl—〉Render—〉RenderContents—〉RenderChildren):
HtmlTextWrite的各種方法的參數取值用到三種枚舉類型:HtmlTextWriteTag、HtmlTextWriteAttribute和HtmlTextWriteStyle,在這裡不作詳細的講解,舉例如下,效果如的圖2:
[DefaultProperty("Text")]
[ToolboxData("<{0}:WebCustomControl1 runat=server></{0}:WebCustomControl1>")]
public class WebCustomControl1 : WebControl
{
protected override void Render(HtmlTextWriter output)
{
// -----------------------------------------------------------------------------
// 第一種方式,通過Add + [Attribute、StyleAttribute、BeginTag\EndTag]
// AddAttribute、AddStyleAttribute在RenderBeginTag和RenderEndTag之前
output.BeginRender(); // 開始Render
output.AddAttribute(HtmlTextWriterAttribute.Value, "This is input."); // 使用HtmlTextWriteAttribute枚舉
output.AddStyleAttribute(HtmlTextWriterStyle.BackgroundColor, ColorTranslator.ToHtml(Color.GreenYellow)); // 使用HtmlTextWriteStyle枚舉
output.RenderBeginTag(HtmlTextWriterTag.Input); // 使用HtmlTextWriteTag枚舉
output.RenderEndTag();
output.EndRender(); // 結束Render
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// 第二種方式,通過Write + [Attribute、StyleAttribute、BeginTag\EndTag]
// WriteAttribute、WriteStyleAttribute在WriteBeginTag和WriteEndTag之間
output.WriteBeginTag("input"); // 直接標記的名稱,不使用HtmlTextWriteTag枚舉
output.WriteAttribute("value", "This is input too."); // 直接使用屬性名稱,不使用HtmlTextWriteAttribute枚舉
output.Write(" style=\"");
output.WriteStyleAttribute("background-color", ColorTranslator.ToHtml(Color.Lavender)); // 直接使用樣式標記,不使用HtmlTextWriteStyle枚舉
output.Write("\"");
output.Write(HtmlTextWriter.TagRightChar); // 添加“>”標記
output.WriteEndTag("input");
// -----------------------------------------------------------------------------
// 第二種適用於對html比較熟悉的朋友。
}
}
如果在本文中發現有什麼不妥的地方,請朋友們給與指點,小弟在此先謝過。