ASP.NET2.0服務(wù)器控件之捕獲回傳事件_.Net教程
推薦:ASP.NET的底層的工作機(jī)制介紹關(guān)于ASP.NET的底層的工作機(jī)制,最近園子里討論的甚是火熱。相信很多人都看過Rick Strahl先生的一篇經(jīng)典之作:A low-level Look at the ASP.NET Architecture,經(jīng)Rick Strahl同意,我把他的這篇
1、實(shí)現(xiàn)捕獲回傳事件
如果服務(wù)器控件需要捕獲來自客戶端的回傳事件,并想為該回傳事件自定義服務(wù)器端事件處理邏輯,那么控件必須實(shí)現(xiàn)
System.Web.UI.IPostBackEventHandler接口。下面列舉了該接口定義。
| 以下為引用的內(nèi)容: public interface IPostBackEventHandler { void RaisePostBackEvent(string eventArgument); } |
如上代碼所示,IPostBackEventHandler接口僅包括一個(gè)成員方法RaisePostBackEvent。該方法使服務(wù)器控件能夠處理將窗體發(fā)送到服務(wù)器時(shí)引發(fā)的事件,其參數(shù)eventArgument表示要傳遞到事件處理程序的可選事件參數(shù)。開發(fā)人員可以在RaisePostBackEvent方法中實(shí)現(xiàn)服務(wù)器控件回傳過程中執(zhí)行的邏輯。一般情況下,RaisePostBackEvent方法將引發(fā)一個(gè)或者多個(gè)服務(wù)器端事件。以下代碼片段顯示了在服務(wù)器上引發(fā)Click事件的RaisePostBackEvent實(shí)現(xiàn)。
| 以下為引用的內(nèi)容: public void RaisePostBackEvent(String eventArgument) { OnClick(EventArgs.Empty); } |
實(shí)現(xiàn)捕獲回傳事件并不是僅僅使服務(wù)器控件類實(shí)現(xiàn)IPostBackEventHandler接口,并實(shí)現(xiàn)該接口成員方法就可以的。開發(fā)人員還需要注意實(shí)現(xiàn)其他內(nèi)容。下面列舉了實(shí)現(xiàn)捕獲回傳事件過程中的三個(gè)要點(diǎn)。
第一、也是最重要的,即自定義服務(wù)器控件類必須實(shí)現(xiàn)IPostBackEventHandler接口,并實(shí)現(xiàn)該接口成員RaisePostBackEvent方法。這一過程在上文中已經(jīng)進(jìn)行了介紹。
第二、為控件分配UniqueID。
定義引起回傳事件的控件的name屬性值為UniqueID,是正確實(shí)現(xiàn)RaisePostBackEvent方法的關(guān)鍵之一。當(dāng)引發(fā)回傳后,頁框架就會(huì)搜索發(fā)送的內(nèi)容,并確定發(fā)送對象的名稱是否與實(shí)現(xiàn)IPostBackEventHandler的服務(wù)器控件的UniqueID對應(yīng)。如果對應(yīng),頁框架就會(huì)在該控件上調(diào)用RaisePostBackEvent方法。這里的重點(diǎn)是需要開發(fā)人員在呈現(xiàn)邏輯中,為控件的name屬性分配UniqueID。下面列舉了一個(gè)簡單的代碼示例。
| 以下為引用的內(nèi)容: protected override void Render(HtmlTextWriter output) { output.Write("<INPUT TYPE=submit name=" this.UniqueID "Value='Click Me' />"); } |
如上代碼所示,在控件呈現(xiàn)方法Render中,呈現(xiàn)了一個(gè)按鈕,其name屬性值為UniqueID。只有為引起回傳的控件的name屬性分配了UniqueID,才能夠正確實(shí)現(xiàn)捕獲回傳事件。
第三、實(shí)現(xiàn)事件屬性結(jié)構(gòu)。
事件屬性結(jié)構(gòu)是一種優(yōu)化的事件實(shí)現(xiàn)方式。在介紹之前,我們首先看看常見的控件事件實(shí)現(xiàn)方式。具體代碼如下所示。
| 以下為引用的內(nèi)容: ...... public class WebCustomControl:WebControl,IPostBackEventHandler{ //聲明Click事件委托 public event EventHandler Click; //實(shí)現(xiàn)RaisePostBackEvent方法 void IPostBackEventHandler.RaisePostBackEvent(string eventArgument) { OnClick(EventArgs.Empty); } //定義OnClick事件處理程序 protected virtual void OnClick(EventArgs e) { if(Click != null) { Click(this,e); } } ...... } |
在以上代碼中,包括了與事件定義相關(guān)的三個(gè)關(guān)鍵內(nèi)容:一、定義Click事件委托;二、控件類實(shí)現(xiàn)了IPostBackEventHandler接口,其中當(dāng)實(shí)現(xiàn)接口成員方法RaisePostBackEvent過程中,定義了事件處理程序OnClick;三、實(shí)現(xiàn)OnClick事件處理程序。以上實(shí)現(xiàn)方法簡單易用,然而卻存在一個(gè)缺點(diǎn),即執(zhí)行效率低。尤其是在一個(gè)類中引發(fā)多個(gè)事件的情況下,將會(huì)增加開銷,浪費(fèi)大量服務(wù)器資源,最終導(dǎo)致運(yùn)行效率降低。
為了解決以上問題,下面介紹一種優(yōu)化的事件實(shí)現(xiàn)方式--事件屬性結(jié)構(gòu)。該結(jié)構(gòu)使用System.ComponentModel.EventHandlerList類,這個(gè)類提供一個(gè)簡單的委托列表。通過使用該類所提供的相關(guān)方法,開發(fā)人員能夠靈活的操作控件的事件處理程序委托列表。例如,控件中的Click事件,使用事件屬性結(jié)構(gòu)如下:
| 以下為引用的內(nèi)容: protected static readonly object EventClick = new object(); public event EventHandler Click{ add { Events.AddHandler(EventClick,value); } remove { Events.RemoveHandler(EventClick,value); } } |
在事件屬性結(jié)構(gòu)定義之前,首先需要定義Click事件委托對象。由于每個(gè)事件僅創(chuàng)建一次,因此,需要聲明為靜態(tài)和只讀的。然后,在屬性結(jié)構(gòu)中通過AddHandler、RemoveHandler方法操作事件處理程序委托列表。當(dāng)頁面調(diào)用Click事件時(shí),它向控件的EventHandlerList集合中添加或者刪除處理程序。由于這種實(shí)現(xiàn)方法,在多個(gè)事件的聲明過程中比普通的實(shí)現(xiàn)方法效率高,因此是非常值得推薦的方法。
另外,在OnClick方法的實(shí)現(xiàn)過程中,當(dāng)用一個(gè)事件屬性時(shí),必須從EventHandlerList中取回委托,并將其轉(zhuǎn)換成EventHandler的類型。
| 以下為引用的內(nèi)容: protected virtual void OnClick(EventArgs e){ EventHandler clickHandler = (EventHandler)Events[EventClick]; if(clickHandler != null) { clickHandler(this,e); } } |
請讀者注意:事件屬性結(jié)構(gòu)不適用于VB.NET語言,只能在C#等語言中應(yīng)用。
2、典型應(yīng)用
實(shí)事求是的講,以上捕獲回傳事件的理論介紹對于從未實(shí)現(xiàn)過服務(wù)器控件事件的讀者而言,有些難以理解。為此,本小節(jié)通過一個(gè)典型的示例來具體說明捕獲回傳事件的實(shí)現(xiàn)方法。
本例實(shí)現(xiàn)了一個(gè)自定義服務(wù)器控件WebCustomControl。該控件雖然呈現(xiàn)為一個(gè)按鈕外觀,但是其并不是從Button類繼承而來。當(dāng)單擊該按鈕時(shí),控件將引起回傳,服務(wù)器端自動(dòng)捕獲回傳的單擊事件,并且引發(fā)Click事件,執(zhí)行對應(yīng)事件處理程序。下面是服務(wù)器控件實(shí)現(xiàn)的源代碼代碼:
| 以下為引用的內(nèi)容: using System; protected override void RenderContents(HtmlTextWriter output) { |
在WebCustomControl類中,實(shí)現(xiàn)了以下有關(guān)捕獲回傳事件處理的關(guān)鍵內(nèi)容:
·控件類WebCustomControl實(shí)現(xiàn)IPostBackEventHandler;
·將引發(fā)回傳的控件的name屬性值設(shè)置UniqueID;
·實(shí)現(xiàn)事件屬性結(jié)構(gòu),維護(hù)事件處理程序委托列表;
·在RaisePostBackEvent方法中調(diào)用OnClick方法;
下面的代碼是應(yīng)用自定義按鈕WebCustomControl的Default.aspx源代碼,顯示效果如圖1和圖2所示。
| 以下為引用的內(nèi)容: <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %> <%@ Register TagPrefix="cc" Namespace="WebControlLibrary" Assembly="WebControlLibrary" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <script runat="server"> void wcc1_Click(object sender, EventArgs e) { message.Text = "您剛才點(diǎn)擊了上面的按鈕"; } </script> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title>捕獲回傳事件</title> </head> <body> <form id="form1" runat="server"> <center> <cc:WebCustomControl ID="wcc1" runat="server" OnClick="wcc1_Click" /> <br /> <br /> <asp:Label ID="message" runat="server"></asp:Label> </center> </form> </body> </html> |
另外,還有一個(gè)與捕獲回傳事件密切相關(guān)的屬性AutoPostBack。該屬性用于控件的自動(dòng)回傳設(shè)置,很多標(biāo)準(zhǔn)的服務(wù)器控件中均包含該屬性。對于開發(fā)人員來講,是否需要在自行創(chuàng)建的服務(wù)器控件中定義該屬性是很重要的,需要根據(jù)控件的功能需求認(rèn)真考慮取舍。該屬性的關(guān)鍵代碼實(shí)現(xiàn)如下:
| 以下為引用的內(nèi)容: //定義屬性AutoPostBack public bool AutoPostBack{ set { this._autoPostBack = value; } get { return this._autoPostBack; } } //在Render方法中添加Page.GetPostBackEventReference()方法 protected override void Render(HtmlTextWriter output){ ...... if(this.AutoPostBack) { writer.WriteAttribute("ontextchanged","javascript:" Page.GetPostBackEventReference(this)); } ...... } |
由以上代碼可知,AutoPostBack屬性的實(shí)現(xiàn)重點(diǎn)是Page.GetPostBackEventReference方法的應(yīng)用。該方法獲取對客戶端腳本函數(shù)的引用,調(diào)用該函數(shù)將使服務(wù)器發(fā)送回該頁,并返回一段表示客戶端事件的字符串,實(shí)際是一些客戶端代碼。當(dāng)AutoPostBack="true"時(shí),服務(wù)器控件將發(fā)生自動(dòng)回傳,而不需通過Click事件等引發(fā);當(dāng)AutoPostBack="false",則回傳必須經(jīng)過類似Click的事件引發(fā)。
以上介紹的是有關(guān)捕獲回傳事件的具體實(shí)現(xiàn)方法。總體來講不是非常復(fù)雜,然而,實(shí)現(xiàn)捕獲回傳事件的具體應(yīng)用非常靈活,遠(yuǎn)遠(yuǎn)沒有這么簡單,這就需要讀者不斷的實(shí)踐才能深入理解。
3、小結(jié)
本文首先介紹了利用ASP.NET 2.0技術(shù),為自定義服務(wù)器控件實(shí)現(xiàn)捕獲回傳事件的實(shí)現(xiàn)方法。通過這些內(nèi)容,相信讀者可以基本掌握實(shí)現(xiàn)控件捕獲回傳事件的方法。在隨后的文章中,筆者將繼續(xù)介紹實(shí)現(xiàn)事件處理的另一核心內(nèi)容--處理回傳數(shù)據(jù)。
分享:保護(hù)你的DLL和Code不被別人使用大家做項(xiàng)目開發(fā)一般都是分層的,比如UI層,業(yè)務(wù)層,數(shù)據(jù)訪問層。業(yè)務(wù)層引用數(shù)據(jù)訪問層的DLL(比如dataAccess.dll),并使用dataAccess.dll中的方法。當(dāng)項(xiàng)目完成并給客戶用了,可有些心里BT的客戶
- asp.net如何得到GRIDVIEW中某行某列值的方法
- .net SMTP發(fā)送Email實(shí)例(可帶附件)
- js實(shí)現(xiàn)廣告漂浮效果的小例子
- asp.net Repeater 數(shù)據(jù)綁定的具體實(shí)現(xiàn)
- Asp.Net 無刷新文件上傳并顯示進(jìn)度條的實(shí)現(xiàn)方法及思路
- Asp.net獲取客戶端IP常見代碼存在的偽造IP問題探討
- VS2010 水晶報(bào)表的使用方法
- ASP.NET中操作SQL數(shù)據(jù)庫(連接字符串的配置及獲取)
- asp.net頁面?zhèn)髦禍y試實(shí)例代碼
- DataGridView - DataGridViewCheckBoxCell的使用介紹
- asp.net中javascript的引用(直接引入和間接引入)
- 三層+存儲(chǔ)過程實(shí)現(xiàn)分頁示例代碼
.Net教程Rss訂閱編程教程搜索
.Net教程推薦
- ASP.NET立即上手教程(9)
- 講解asp.net的異常處理機(jī)制
- 解析WPF實(shí)現(xiàn)音頻文件循環(huán)順序播放的解決方法
- 解析五種ADO.NET數(shù)據(jù)庫連接知識
- 解讀ASP.NET如何實(shí)現(xiàn)靜態(tài)的TreeView控件導(dǎo)航
- 怎樣處理.NET開發(fā)事件
- ASP.NET 2.0高級數(shù)據(jù)處理之?dāng)?shù)據(jù)綁定
- 轉(zhuǎn)換DataSet到普通xml的新法
- 怎樣用Asp.net代碼在虛擬主機(jī)實(shí)現(xiàn)Urlrewrite
- 深入本機(jī)影像生成器(Ngen.exe)工具使用方法詳解
- 相關(guān)鏈接:
- 教程說明:
.Net教程-ASP.NET2.0服務(wù)器控件之捕獲回傳事件
。