asp.net控件开发基础(2)
生活随笔
收集整理的這篇文章主要介紹了
asp.net控件开发基础(2)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
上一篇:http://www.cnblogs.com/Clingingboy/archive/2006/07/30/463471.html
或許大家還對為何要重寫Render方法存有疑惑,希望大家看看我舉的例子,能夠明白Render方法和其他兩個方法的作用,然后真正明白為何一般情況下只須重寫Render方法
我們知道我們每次編寫控件時,都需要重寫Render方法,我們發現在Control類中很多方法可以重寫,但我們沒有去重寫他們,我們需要遵循一個原則,在需要重載的時候再去重寫他們
我們還是先來看看與Render方法相關的兩個方法
//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控件,如下圖
圖一
我們知道,每個控件都有Visible和EnableViewState屬性,Visible用來設置控件是否被呈現.
圖二
現在我們把button控件的Visible屬性設置為flase,我們看到了我們預期的效果,接著請啟用頁面跟蹤,這個很重要
圖三
在服務器上運行這個頁面,大家可以在控件樹上看到下面畫面
圖四
(1)System.Web.UI.LiteralControl
大家可以看到,在我們定義的每個控件之間都有System.Web.UI.LiteralControl.
這里需要說明的是,要理解任何不需要在服務器上處理的任何其他字符串.
如何理解呢?大家打開這個運行頁面的源代碼頁面,如下代碼,大家看到沒有,除了服務器控件外,我們有其他元素(不需要在服務器上處理的任何其他字符串),包括空格.
示例一 <!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>
?<div>
?<span?id="Label1">Label</span><br?/>
?<br?/>
?<input?name="TextBox1"?type="text"?id="TextBox1"?/><br?/>
?<br?/>
?<br?/>
?<br?/>
?<div?id="Panel1"?style="height:50px;width:125px;">
??
?
</div>
? </div>
?
<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..以下的標簽無空格的寫在了一起.看下面修改后的代碼
示例二 <%@?Page?Language="C#"?AutoEventWireup="true"?CodeFile="Default2.aspx.cs"?Inherits="Default2"?Trace="true"?%>
<!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?runat="server">
?<title>無標題頁</title>
</head>
<body>
?<form?id="form1"?runat="server"><asp:Label?ID="Label1"?runat="server"?Text="Label"></asp:Label><asp:TextBox?ID="TextBox1"?runat="server"></asp:TextBox><asp:Button?ID="Button1"?runat="server"?Text="Button"?Visible="False"?/><asp:Panel?ID="Panel1"?runat="server"?Height="50px"?Width="125px"></asp:Panel></form>
</body>
</html>
運行效果
圖五
現在發現控件之間已經沒有System.Web.UI.LiteralControl了,因為我去掉了空格.這個也說明了一點,如果代碼很亂的話會影響速度.現在大家應該明白System.Web.UI.LiteralControl的意思了吧.
(2)大家繼續看圖四的Button1,大家會發現它呈現的大小字節數為0,因為我們設置了Button1的Visible值為False,所以未呈現此控件.
下面我們來理解這一點,大家重新看到RenderControl方法,如果Visible值為True則呈現此控件.
if(Visible)
?Render(writer);
為了理解這個方法,我們來重寫此方法,我們以第一次講的CreditCardForm3控件為例
我們重寫RenderControl方法,把Render方法的代碼全部拷貝到RenderControl方法中,然后去掉Render方法
然后在asp.net頁面使用此控件,定義其Visible值為False
圖六
運行這個例子以后,你會發現控件還是呈現了,就是因為你重寫了RenderControl方法,使控件的Visible值無效了
所以我們就要加上一個判斷
if(Visible)?{}
否則的話,此方法呈現的內容沒有Visible值.為了更加深刻理解這一點,我們重寫基類的RenderControl方法的方法.
base.RenderControl(writer);
你會發現在頁面呈現時的控件有兩個,一個在RenderControl方法方法輸出,一個在Render方法輸出,因為
base.RenderControl方法調用了Render方法,當設置控件Visible屬性為False時,Render方法輸出的內容被隱藏(未被呈現,而RenderControl方法輸出的內容仍然存在.現在大家應該了解RenderControl方法的作用了吧.
如果服務器控件的 Visible 屬性設置為 true,則向頁呈現服務器控件的內容,所以一般情況下我們不重寫此方法.因為一般控件都需要Visible 屬性,除非特殊情況.
圖七
(3)RenderChildren方法
再重新看到圖四,大家可以看到,我們拖放的控件是在屬于form1的子控件,panel控件是一個容器控件,因為下面沒拖放控件,任何其他顯示的字符串表現為System.Web.UI.LiteralControl,大家可以拖幾個控件到panel里再重新運行看看,會發現拖進去的控件變為panel的子控件.最明顯的的測試方法是Wizard控件,拖放一個Wizard控件然后再測試你就會明白了.
RenderChildren方法則判斷當前控件是否有子控件,如果有,則根據RenderControl方法判斷控件的Visible值來呈現控件.所以大家在重寫Render方法時,不重寫基類Render方法時,將無法實現RenderChildren方法.帶來的后果將是無法呈現子控件.
下面我們來測試一下.我們還是以CreditCardForm3控件為例子(請先把RenderControl方法的內容全注釋掉),當未重實現RenderChildren方法時則無法呈現子控件內容,請啟動跟蹤
將發現其子控件呈現字節為0
圖八
由于CreditCardForm3繼承了CreditCardForm2,所以重寫基類Render方法將會重復輸出,我們可以直接在Render方法中重寫RenderChildren方法.再來測試.將會發現有些變化
發現其子控件呈現字節并非為0,而是10
圖九
說明其子控件還是存在東西的,只不過沒有用而已,所以大家可以根據實際需求來確實是否要重寫RenderChildren方法,一般的話都會重寫Render方法,這樣保險一點
好了,現在再來回顧下剛開始給出的代碼,通過上面的試驗,你是否明白了?
呈現控件的步驟(注意:下面三個方法都可以呈現,不過我們已經說過了,像在RenderControl方法用HtmlTextWriter預先輸出的話,就喪失Visible的功能(說不定你就不需要這個功能,那時你就可以重寫這個方法了)
(1)RenderControl方法
先判斷其Visible然后調用Render方法
(2) Render方法
使用HtmlTextWriter將標記字符和文本輸出然后調用RenderChildren方法
(3)RenderChildren方法
判斷當前控件是否有子控件,然后再調用RenderControl方法根據子控件的Visible值輸出子控件.
我們了解上面三個方法后,就會知道,一般情況下,我們無須重寫RenderControl方法和RenderChildren方法.所以最合適的就是重寫Render方法了.說了一大堆.目的就是為了說明為什么要重寫Render方法.
上次,忘了把代碼傳上了,不小心只上傳了dll文件,不好意思.這次就寫這么多.希望大家能夠真正明白.大家可以適當的修改代碼,這樣你會發現更多.
參考文章:ASP.NET2.0服務器控件之Render方法
點擊下載示例代碼
如果有什么錯誤請大家指出,希望多跟大家交流^_^
或許大家還對為何要重寫Render方法存有疑惑,希望大家看看我舉的例子,能夠明白Render方法和其他兩個方法的作用,然后真正明白為何一般情況下只須重寫Render方法
我們知道我們每次編寫控件時,都需要重寫Render方法,我們發現在Control類中很多方法可以重寫,但我們沒有去重寫他們,我們需要遵循一個原則,在需要重載的時候再去重寫他們
我們還是先來看看與Render方法相關的兩個方法
//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控件,如下圖
圖一
我們知道,每個控件都有Visible和EnableViewState屬性,Visible用來設置控件是否被呈現.
圖二
現在我們把button控件的Visible屬性設置為flase,我們看到了我們預期的效果,接著請啟用頁面跟蹤,這個很重要
圖三
在服務器上運行這個頁面,大家可以在控件樹上看到下面畫面
圖四
(1)System.Web.UI.LiteralControl
大家可以看到,在我們定義的每個控件之間都有System.Web.UI.LiteralControl.
這里需要說明的是,要理解任何不需要在服務器上處理的任何其他字符串.
如何理解呢?大家打開這個運行頁面的源代碼頁面,如下代碼,大家看到沒有,除了服務器控件外,我們有其他元素(不需要在服務器上處理的任何其他字符串),包括空格.
示例一 <!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>
?<div>
?<span?id="Label1">Label</span><br?/>
?<br?/>
?<input?name="TextBox1"?type="text"?id="TextBox1"?/><br?/>
?<br?/>
?<br?/>
?<br?/>
?<div?id="Panel1"?style="height:50px;width:125px;">
??
?
</div>
? </div>
?
<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..以下的標簽無空格的寫在了一起.看下面修改后的代碼
示例二 <%@?Page?Language="C#"?AutoEventWireup="true"?CodeFile="Default2.aspx.cs"?Inherits="Default2"?Trace="true"?%>
<!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?runat="server">
?<title>無標題頁</title>
</head>
<body>
?<form?id="form1"?runat="server"><asp:Label?ID="Label1"?runat="server"?Text="Label"></asp:Label><asp:TextBox?ID="TextBox1"?runat="server"></asp:TextBox><asp:Button?ID="Button1"?runat="server"?Text="Button"?Visible="False"?/><asp:Panel?ID="Panel1"?runat="server"?Height="50px"?Width="125px"></asp:Panel></form>
</body>
</html>
運行效果
圖五
現在發現控件之間已經沒有System.Web.UI.LiteralControl了,因為我去掉了空格.這個也說明了一點,如果代碼很亂的話會影響速度.現在大家應該明白System.Web.UI.LiteralControl的意思了吧.
(2)大家繼續看圖四的Button1,大家會發現它呈現的大小字節數為0,因為我們設置了Button1的Visible值為False,所以未呈現此控件.
下面我們來理解這一點,大家重新看到RenderControl方法,如果Visible值為True則呈現此控件.
if(Visible)
?Render(writer);
為了理解這個方法,我們來重寫此方法,我們以第一次講的CreditCardForm3控件為例
我們重寫RenderControl方法,把Render方法的代碼全部拷貝到RenderControl方法中,然后去掉Render方法
然后在asp.net頁面使用此控件,定義其Visible值為False
圖六
運行這個例子以后,你會發現控件還是呈現了,就是因為你重寫了RenderControl方法,使控件的Visible值無效了
所以我們就要加上一個判斷
if(Visible)?{}
否則的話,此方法呈現的內容沒有Visible值.為了更加深刻理解這一點,我們重寫基類的RenderControl方法的方法.
base.RenderControl(writer);
你會發現在頁面呈現時的控件有兩個,一個在RenderControl方法方法輸出,一個在Render方法輸出,因為
base.RenderControl方法調用了Render方法,當設置控件Visible屬性為False時,Render方法輸出的內容被隱藏(未被呈現,而RenderControl方法輸出的內容仍然存在.現在大家應該了解RenderControl方法的作用了吧.
如果服務器控件的 Visible 屬性設置為 true,則向頁呈現服務器控件的內容,所以一般情況下我們不重寫此方法.因為一般控件都需要Visible 屬性,除非特殊情況.
圖七
(3)RenderChildren方法
再重新看到圖四,大家可以看到,我們拖放的控件是在屬于form1的子控件,panel控件是一個容器控件,因為下面沒拖放控件,任何其他顯示的字符串表現為System.Web.UI.LiteralControl,大家可以拖幾個控件到panel里再重新運行看看,會發現拖進去的控件變為panel的子控件.最明顯的的測試方法是Wizard控件,拖放一個Wizard控件然后再測試你就會明白了.
RenderChildren方法則判斷當前控件是否有子控件,如果有,則根據RenderControl方法判斷控件的Visible值來呈現控件.所以大家在重寫Render方法時,不重寫基類Render方法時,將無法實現RenderChildren方法.帶來的后果將是無法呈現子控件.
下面我們來測試一下.我們還是以CreditCardForm3控件為例子(請先把RenderControl方法的內容全注釋掉),當未重實現RenderChildren方法時則無法呈現子控件內容,請啟動跟蹤
將發現其子控件呈現字節為0
圖八
由于CreditCardForm3繼承了CreditCardForm2,所以重寫基類Render方法將會重復輸出,我們可以直接在Render方法中重寫RenderChildren方法.再來測試.將會發現有些變化
發現其子控件呈現字節并非為0,而是10
圖九
說明其子控件還是存在東西的,只不過沒有用而已,所以大家可以根據實際需求來確實是否要重寫RenderChildren方法,一般的話都會重寫Render方法,這樣保險一點
好了,現在再來回顧下剛開始給出的代碼,通過上面的試驗,你是否明白了?
呈現控件的步驟(注意:下面三個方法都可以呈現,不過我們已經說過了,像在RenderControl方法用HtmlTextWriter預先輸出的話,就喪失Visible的功能(說不定你就不需要這個功能,那時你就可以重寫這個方法了)
(1)RenderControl方法
先判斷其Visible然后調用Render方法
(2) Render方法
使用HtmlTextWriter將標記字符和文本輸出然后調用RenderChildren方法
(3)RenderChildren方法
判斷當前控件是否有子控件,然后再調用RenderControl方法根據子控件的Visible值輸出子控件.
我們了解上面三個方法后,就會知道,一般情況下,我們無須重寫RenderControl方法和RenderChildren方法.所以最合適的就是重寫Render方法了.說了一大堆.目的就是為了說明為什么要重寫Render方法.
上次,忘了把代碼傳上了,不小心只上傳了dll文件,不好意思.這次就寫這么多.希望大家能夠真正明白.大家可以適當的修改代碼,這樣你會發現更多.
參考文章:ASP.NET2.0服務器控件之Render方法
點擊下載示例代碼
如果有什么錯誤請大家指出,希望多跟大家交流^_^
轉載于:https://www.cnblogs.com/wayne-ivan/archive/2006/09/18/507622.html
總結
以上是生活随笔為你收集整理的asp.net控件开发基础(2)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SQL Server 2000 JDBC
- 下一篇: [BTS06]BizTalk2006 S