天天看點

一起談.NET技術,asp.net控件開發基礎(2)

  或許大家還對為何要重寫Render方法存有疑惑,希望大家看看我舉的例子,能夠明白Render方法和其他兩個方法的作用,然後真正明白為何一般情況下隻須重寫Render方法。我們知道我們每次編寫控件時,都需要重寫Render方法,我們發現在Control類中很多方法可以重寫,但我們沒有去重寫他們,我們需要遵循一個原則,在需要重載的時候再去重寫他們

  我們還是先來看看與Render方法相關的兩個方法

一起談.NET技術,asp.net控件開發基礎(2)

//RenderControl方法的基本實作

public void RenderControl(HtmlTextWriter writer)

{

if(Visible)

Render(writer);

}

//Render方法基本實作

protected virtual void Render(HtmlTextWriter writer)

RenderChildren(writer);

//RenderChildren方式基本實作

protected virtual void RenderChildren(HtmlTextWriter writer)

foreach (Control c in Controls)

c.RenderControl(writer);

  相信看過"ASP.NET伺服器控件開發技術與執行個體"這本書的人,肯定看過上面的一段代碼.

  假設你不了解上面的流程(我也不一定了解,希望我的思路對你有幫助),我認為有一種很好的方式來了解上面的流程,跟大家分享一下。現在抛開上面的代碼,我們來建一個簡單的頁面,随意的拖幾個控件到界面上,注意最後一個三panel控件,如下圖

一起談.NET技術,asp.net控件開發基礎(2)

圖一

  我們知道,每個控件都有Visible和EnableViewState屬性,Visible用來設定控件是否被呈現.

一起談.NET技術,asp.net控件開發基礎(2)

圖二

  現在我們把button控件的Visible屬性設定為flase,我們看到了我們預期的效果,接着請啟用頁面跟蹤,這個很重要

一起談.NET技術,asp.net控件開發基礎(2)

圖三

  在伺服器上運作這個頁面,大家可以在控件樹上看到下面畫面

一起談.NET技術,asp.net控件開發基礎(2)

圖四

  (1)System.Web.UI.LiteralControl

  大家可以看到,在我們定義的每個控件之間都有System.Web.UI.LiteralControl。 這裡需要說明的是,要了解任何不需要在伺服器上處理的任何其他字元串。如何了解呢?大家打開這個運作頁面的源代碼頁面,如下代碼,大家看到沒有,除了伺服器控件外,我們有其他元素(不需要在伺服器上處理的任何其他字元串),包括空格。

示例一

一起談.NET技術,asp.net控件開發基礎(2)

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >

<head><title>

鏃犳爣棰橀〉

</title></head>

<body>

<form name="form1" method="post" action="Default1.aspx" id="form1">

<div>

<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/wEPDwULLTExNTUxMDYxODdkZHVaWm47e5anDettRKviGvS0nDWQ" />

</div>

<span id="Label1">Label</span><br />

<br />

<input name="TextBox1" type="text" id="TextBox1" /><br />

<div id="Panel1" style="height:50px;width:125px;">

 </div>

<input type="hidden" name="__EVENTVALIDATION" id="__EVENTVALIDATION" value="/wEWAgK/5/fTBwLs0bLrBrVw7YrSp5G/l4sJGPkKN/asFj2W" />

</div></form>

</body>

</html>

  為了讓大家更加明白System.Web.UI.LiteralControl的意思的,讓我們來修改HTML頁面,說明:以上代碼為運作後的HTML源代碼.而不是我們所說的源代碼,大家應該明白我所指的源代碼的意思。我們來修改代碼,注意:我把<form..以下的标簽無空格的寫在了一起.看下面修改後的代碼

示例二

  運作效果

一起談.NET技術,asp.net控件開發基礎(2)

圖五

  現在發現控件之間已經沒有System.Web.UI.LiteralControl了,因為我去掉了空格.這個也說明了一點,如果代碼很亂的話會影響速度.現在大家應該明白System.Web.UI.LiteralControl的意思了吧.

  (2)大家繼續看圖四的Button1,大家會發現它呈現的大小位元組數為0,因為我們設定了Button1的Visible值為False,是以未呈現此控件.

  下面我們來了解這一點,大家重新看到RenderControl方法,如果Visible值為True則呈現此控件.

一起談.NET技術,asp.net控件開發基礎(2)
一起談.NET技術,asp.net控件開發基礎(2)

 Render(writer);

  為了了解這個方法,我們來重寫此方法,我們以第一次講的CreditCardForm3控件為例。我們重寫RenderControl方法,把Render方法的代碼全部拷貝到RenderControl方法中,然後去掉Render方法。然後在asp.net頁面使用此控件,定義其Visible值為False

一起談.NET技術,asp.net控件開發基礎(2)

圖六

  運作這個例子以後,你會發現控件還是呈現了,就是因為你重寫了RenderControl方法,使控件的Visible值無效了,是以我們就要加上一個判斷

一起談.NET技術,asp.net控件開發基礎(2)
一起談.NET技術,asp.net控件開發基礎(2)

if(Visible) 

一起談.NET技術,asp.net控件開發基礎(2)
一起談.NET技術,asp.net控件開發基礎(2)
一起談.NET技術,asp.net控件開發基礎(2)

  否則的話,此方法呈現的内容沒有Visible值.為了更加深刻了解這一點,我們重寫基類的RenderControl方法的方法.

一起談.NET技術,asp.net控件開發基礎(2)

base.RenderControl(writer);

  你會發現在頁面呈現時的控件有兩個,一個在RenderControl方法方法輸出,一個在Render方法輸出,因為base.RenderControl方法調用了Render方法,當設定控件Visible屬性為False時,Render方法輸出的内容被隐藏(未被呈現,而RenderControl方法輸出的内容仍然存在.現在大家應該了解RenderControl方法的作用了吧.

  如果伺服器控件的 Visible 屬性設定為 true,則向頁呈現伺服器控件的内容,是以一般情況下我們不重寫此方法.因為一般控件都需要Visible 屬性,除非特殊情況.

一起談.NET技術,asp.net控件開發基礎(2)

圖七

  (3)RenderChildren方法

  再重新看到圖四,大家可以看到,我們拖放的控件是在屬于form1的子控件,panel控件是一個容器控件,因為下面沒拖放控件,任何其他顯示的字元串表現為System.Web.UI.LiteralControl,大家可以拖幾個控件到panel裡再重新運作看看,會發現拖進去的控件變為panel的子控件.最明顯的的測試方法是Wizard控件,拖放一個Wizard控件然後再測試你就會明白了.

  RenderChildren方法則判斷目前控件是否有子控件,如果有,則根據RenderControl方法判斷控件的Visible值來呈現控件.是以大家在重寫Render方法時,不重寫基類Render方法時,将無法實作RenderChildren方法.帶來的後果将是無法呈現子控件.

  下面我們來測試一下.我們還是以CreditCardForm3控件為例子(請先把RenderControl方法的内容全注釋掉),當未重實作RenderChildren方法時則無法呈現子控件内容,請啟動跟蹤。将發現其子控件呈現位元組為0

一起談.NET技術,asp.net控件開發基礎(2)

圖八

  由于CreditCardForm3繼承了CreditCardForm2,是以重寫基類Render方法将會重複輸出,我們可以直接在Render方法中重寫RenderChildren方法.再來測試.将會發現有些變化,發現其子控件呈現位元組并非為0,而是10

一起談.NET技術,asp.net控件開發基礎(2)

圖九

  說明其子控件還是存在東西的,隻不過沒有用而已,是以大家可以根據實際需求來确實是否要重寫RenderChildren方法,一般的話都會重寫Render方法,這樣保險一點。好了,現在再來回顧下剛開始給出的代碼,通過上面的試驗,你是否明白了?呈現控件的步驟(注意:下面三個方法都可以呈現,不過我們已經說過了,像在RenderControl方法用HtmlTextWriter預先輸出的話,就喪失Visible的功能(說不定你就不需要這個功能,那時你就可以重寫這個方法了)

  (1)RenderControl方法

  先判斷其Visible然後調用Render方法

  (2) Render方法

  使用HtmlTextWriter将标記字元和文本輸出然後調用RenderChildren方法

  判斷目前控件是否有子控件,然後再調用RenderControl方法根據子控件的Visible值輸出子控件。

  我們了解上面三個方法後,就會知道,一般情況下,我們無須重寫RenderControl方法和RenderChildren方法.是以最合适的就是重寫Render方法了.說了一大堆.目的就是為了說明為什麼要重寫Render方法.

<a href="http://kb.cnblogs.com/page/75286/" target="_blank">上一篇:asp.net控件開發基礎(1)</a> <a href="http://kb.cnblogs.com/page/75320/" target="_blank">下一篇:asp.net控件開發基礎(3)</a>

繼續閱讀