ASP.NET控件開發(fā)之RenderContents使用淺析
ASP.NET控件開發(fā)基礎之RenderContents使用呈現(xiàn)自定義控件的步驟:
ASP.NET控件開發(fā)之RenderContents使用一.從繼承WebControl開始
在第二篇教程中,重點介紹了Render()方法的使用,用來呈現(xiàn)控件,但從Control類繼承的控件尚未發(fā)揮asp.net控件的作用.大家知道web服務器控件分為HTML服務器控件(如﹤input id="Button2" runat="server" type="button" value="button" /﹥這樣的形式)和標準服務器控件(就是﹤asp:.. id="" runat="server" /﹥這樣的形式的控件)
HTML服務器控件的控件從System.Web.UI.HtmlControls.HtmlControl 類派生
標準服務器控件的控件從System.Web.UI.WebControls.WebControl 類派生
HtmlControl 類和WebControl 類則從System.Web.UI.Control 類派生,并擴展.
所以我們說,所有的服務器控件都繼承自System.Web.UI.Control 類,即所有的服務器控件都具有Control 類的共同屬性,如Visible,EnableViewState屬性,HtmlControl 類和WebControl 類則擴充了System.Web.UI.Control 類的功能,如
HtmlControl 類定義了所有 HTML 服務器控件所通用的方法、屬性 (Property) 和事件(具體參數(shù)參照MSDN)
WebControl 類定義了所有 標準服務器控件所通用的方法、屬性 (Property) 和事件(具體參數(shù)參照MSDN)
如每個繼承了WebControl 類的標準控件都有定義外觀和行為的屬性,然后不同控件再根據(jù)需要擴展功能.
所以我們推薦的做法是直接從WebControl 類派生,而非Control類.我們所做的非并從頭開始.從WebControl 類繼承可以幫我們省很多工作.
ASP.NET控件開發(fā)之RenderContents使用二.重寫WebControl類方法,不再是Render()
WebControl類繼承了Control類,當然有Render方法,在WebControl類中重寫了Render方法,如下代碼
示例一
- protected override void Render(HtmlTextWriter output)
- {
- RenderBeginTag(output);
- RenderContents(output);
- RenderEndTag(output);
- }
注意 RebderBeginTag方法并非是HtmlTextWriter類中的方法,而是WebControl類中的方法,表示輸出HTML標簽頭標記,如﹤table .....﹥,RenderEndTag方法則輸出HTML標簽尾標記,如﹤/table﹥.中間的RenderContents方法則就是Control類的Render方法. 看下面RenderContents方法的定義.
示例二
- protected override void RenderContents(HtmlTextWriter output){
- //使用默認邏輯來呈現(xiàn)子控件,那么一定要調用基類中的方法。
- base.Render(output);
- }
接著再看RenderBeginTag方法的定義
示例三
- public virtual void RenderBeginTag(HtmlTextWriter output)
- {
- //添加呈現(xiàn)控件的屬性和樣式
- //AddAttributesToRender為WebControl類中的方法
- AddAttributesToRender(output);
- //呈現(xiàn)控件標簽
- //如label控件呈現(xiàn)﹤span ﹥
- //textbox控件呈現(xiàn)﹤input ﹥
- HtmlTextWriterTag tagKey = TagKey;
- if (tagKey != HtmlTextWriterTag.Unknown)
- {
- output.RenderBeginTag(tagKey);
- }
- else
- {
- output.RenderBeginTag(this.TagName);
- }
- }
這里打個比方,假設你要輸出一個表格,你就必須定義﹤table﹥標簽頭,然后在其內部定義﹤tr﹥,﹤td﹥,下面看Control類中Render方法的實現(xiàn),表明Render方法必須完成所有的任務,包括標簽頭標記﹤table﹥和﹤table﹥標簽的屬性和樣式的輸出.
示例四
- protected override void Render(HtmlTextWriter writer)
- {
- //為table標簽定義屬性和樣式
- writer.AddAttribute(HtmlTextWriterAttribute.Width, "287px");
- writer.AddStyleAttribute(HtmlTextWriterStyle.BorderWidth, "0");
- writer.RenderBeginTag(HtmlTextWriterTag.Table);
- writer.RenderBeginTag(HtmlTextWriterTag.Tr);
- writer.RenderBeginTag(HtmlTextWriterTag.Td);
- writer.Write("﹤strong﹥" + PaymentMethodText + "﹤/strong﹥");
- writer.RenderEndTag();
- writer.RenderBeginTag(HtmlTextWriterTag.Td);
- writer.AddAttribute(HtmlTextWriterAttribute.Name, "PaymentMethod");
- writer.AddAttribute(HtmlTextWriterAttribute.Id, "PaymentMethod");
- writer.AddStyleAttribute(HtmlTextWriterStyle.Width, "100%");
- writer.RenderBeginTag(HtmlTextWriterTag.Select);
- //以下代碼省略
- }
在WebControl類中重寫了Render方法后,直接幫你定義好了標簽,默認情況下為﹤span﹥,可通過重寫TagKey屬性來修改標簽,然后AddAttributesToRender方法為標簽定義樣式和屬性
示例五
- protected override HtmlTextWriterTag TagKey
- {
- get { return HtmlTextWriterTag.Table; }
- }
示例六
- protected override void AddAttributesToRender(HtmlTextWriter writer)
- {
- //為table標簽定義屬性和樣式
- writer.AddAttribute(HtmlTextWriterAttribute.Width, "287px");
- writer.AddStyleAttribute(HtmlTextWriterStyle.BorderWidth, "0");
- base.AddAttributesToRender(writer);
- }
接著重寫RenderContents方法,對比上面的Render方法,實現(xiàn)效果是一樣的
示例七
- protected override void RenderContents(HtmlTextWriter writer)
- {
- //注意,此處無沒有table標簽,只定義其內部標簽
- writer.RenderBeginTag(HtmlTextWriterTag.Tr);
- writer.RenderBeginTag(HtmlTextWriterTag.Td);
- writer.Write(PaymentMethodText);
- writer.RenderEndTag();
- writer.RenderBeginTag(HtmlTextWriterTag.Td);
- writer.AddAttribute(HtmlTextWriterAttribute.Name, PaymentMethodSelectName);
- writer.AddAttribute(HtmlTextWriterAttribute.Id, PaymentMethodSelectId);
- writer.AddStyleAttribute(HtmlTextWriterStyle.Width, "100%");
- writer.RenderBeginTag(HtmlTextWriterTag.Select);
- //以下省略
- }
所以說重寫后的Render方法在默認情況下加了一個標簽,而你可以重寫這個標簽(默認情況下為﹤span﹥).可能大家對其感到奇怪,即然可以實現(xiàn)同樣效果,有必要重寫Render方法,再加一個RenderContents方法嗎?
ASP.NET控件開發(fā)之RenderContents使用三.Render方法和RenderContents方法的區(qū)別
當你繼承WebControl類,在RenderContents方法中實現(xiàn)示例四代碼時,(我們再以以前的例子展示)呈現(xiàn)后的代碼如下,看到沒有,控件ID為﹤span﹥
在RenderContents方法輸入的標簽將成為其內部標簽.再看看這個控件的屬性面板,你會看到很多的繼承自WebControl類的屬性,設置其屬性,即是設置﹤span﹥標簽的屬性.TagKey的作用大概就在于此吧,為了使用WebControl類的公共屬性.(我是這么認為的)而非定義在﹤table﹥標簽上
示例八
- ﹤span id="CreditCardForm5_1"﹥﹤table style="border-width:0;"﹥
- ﹤tr﹥
- ﹤td﹥﹤strong﹥信用卡類型﹤/strong﹥﹤/td﹥﹤td﹥﹤select name="PaymentMethod" id="PaymentMethod" style="width:100%;"﹥
- ......
假設我們稱﹤span﹥里面的﹤table﹥等標簽為子標簽,在RenderContents方法應該定義控件的子標簽,如果你只定義標簽屬性的話,只需重寫AddAttributesToRender方法即可,可不須重寫RenderContents方法.
下面再講下重寫標簽的方法
(1) 重寫TagKey屬性,下面重寫label控件的標簽
- public class Ch4Label: Label
- {
- protected override HtmlTextWriterTag TagKey
- {
- get { return HtmlTextWriterTag.Div; }
- }
- }
(2)重寫基類構造函數(shù),此方法只有在繼承Control類后適用
- public CreditCardForm5() : base(HtmlTextWriterTag.Table) { }
最后總結下:
1.控件繼承自WebControl類
主要原因是WebControl類公共的東西比Control類
2.TagKey
表示控件的標簽,默認情況下為﹤span﹥,可以重寫此屬性修改或者重寫WebControl類的構造函數(shù)
3.AddAttributesToRender方法
為標簽添加屬性和樣式
4.RenderContents方法
在標簽內呈現(xiàn)內容
如果控件不復雜,則可直接從標準控件繼承(如label),再根據(jù)需要擴展,重寫AddAttributesToRender方法,還可以重寫
TagKey更改默認標簽,而無須重寫RenderContents方法.如果控件比較復雜,不是單一的,則需要在RenderContents方法輸出控件的內部的內容.
其實最大的區(qū)別就是默認情況下WebControl類為你加了一個標簽,方便添加WebControl類的一些公共的東西,如果你重寫Render()方法,而舍棄RenderContents方法,你就無福享受WebControl類給你提供的這么多屬性和方法了.
大家多熟悉下WebControl類的一些公共屬性,然后再多改改,可以明白的更加深刻.
我喜歡慢慢的把東西全講全,不然心里不舒服,所以我就慢慢寫了,當然前提是我理解的基礎上.這次的例子,大家可根據(jù)第二篇的代碼適當修改就可.錯誤之處還請指出^_^
ASP.NET控件開發(fā)之RenderContents使用就向你介紹到這里,希望對你了解ASP.NET控件開發(fā)基礎之RenderContents使用有所幫助。
【編輯推薦】