你的位置:睿鑫网络 >> 编程 >> web开发 >> ASP.NET >> 详细内容 在线投稿

ASP.NET2.0服务器控件之捕获回传事件

排行榜 收藏 打印 发给朋友 举报 来源: 网络   发布者:未知
热度10票  浏览33次 时间:2010年1月15日 10:40

QB+xy#ew"R)M x0上一篇文章介绍了实现自定义服务器控件事件的基本概念。本文将通过典型示例讲解捕获回传事件的实现方法。睿鑫网络5?z)~!O[d/H.n2w

睿鑫网络N5F_6tgT)N

1. 实现捕获回传事件睿鑫网络$wv&V7KK

@JLDl$F8YJ0如果服务器控件需要捕获来自客户端的回传事件,并想为该回传事件自定义服务器端事件处理逻辑,那么控件必须实现System.Web.UI.IPostBackEventHandler接口。下面列举了该接口定义。

)i` {s/oD0

8_ ^"o ~8Z?0public interface IPostBackEventHandler

|CHDue w0

a6x2r&]B"~)H0{

9? \ ? aK0d f0

]6mdfZ#q0 void RaisePostBackEvent(string eventArgument);

bD%w6i&Yj5K7]0

Y]#k4b-]U8Qf}0}

s4i#P)o;F0 睿鑫网络;THdhoV"LK

如上代码所示,IPostBackEventHandler接口仅包括一个成员方法RaisePostBackEvent。该方法使服务器控件能够处理将窗体发送到服务器时引发的事件,其参数eventArgument表示要传递到事件处理程序的可选事件参数。开发人员可以在RaisePostBackEvent方法中实现服务器控件回传过程中执行的逻辑。一般情况下,RaisePostBackEvent方法将引发一个或者多个服务器端事件。以下代码片段显示了在服务器上引发Click事件的RaisePostBackEvent实现。睿鑫网络'WqS3M-|)o?%d

U&X5X7})s[z [6[0public void RaisePostBackEvent(String eventArgument)

0x%A1w~8Q|,A Kx(T D0

'l_8F8y]%mj8BO0{睿鑫网络:R%dF0u;S!f2X

睿鑫网络nS8d}7Dp/S3P/u

 OnClick(EventArgs.Empty);睿鑫网络wj2V'W"h V o

睿鑫网络,p$x?8__f"]

}睿鑫网络H-f`5zg

fH$^Ub$U0实现捕获回传事件并不是仅仅使服务器控件类实现IPostBackEventHandler接口,并实现该接口成员方法就可以的。开发人员还需要注意实现其他内容。下面列举了实现捕获回传事件过程中的三个要点。

qE@bYu,q5{0 睿鑫网络H M&sd(}#B

第一,也是最重要的,即自定义服务器控件类必须实现IPostBackEventHandler接口,并实现该接口成员RaisePostBackEvent方法。这一过程在上文中已经进行了介绍。

Q;}t4X$UiD0

`1ZYsQ.^#dI^g0第二,为控件分配UniqueID。

e^]:E3s3I3U7I7bM n0 睿鑫网络5d/o4JAB3\ |

定义引起回传事件的控件的name属性值为UniqueID,是正确实现RaisePostBackEvent方法的关键之一。当引发回传后,页框架就会搜索发送的内容,并确定发送对象的名称是否与实现IPostBackEventHandler的服务器控件的UniqueID对应。如果对应,页框架就会在该控件上调用RaisePostBackEvent方法。这里的重点是需要开发人员在呈现逻辑中,为控件的name属性分配UniqueID。下面列举了一个简单的代码示例。睿鑫网络5p i(\xy?,eBX

a"O$]"\ x&K$[+V&T!_0protected override void Render(HtmlTextWriter output)睿鑫网络7M1o-G!ld iK8A

GZ l` Z!^$D$[$f0{

3H9akO;U1r6[0

"R+[)} ~/n?EQ0 output.Write("");睿鑫网络n`P0hzL5g(I

~T&i ZVVJ;Ik0}

+zg8t8J:z^S;jO8j0 睿鑫网络@;E V,IBK$Iw(z

如上代码所示,在控件呈现方法Render中,呈现了一个按钮,其name属性值为UniqueID。只有为引起回传的控件的name属性分配了UniqueID,才能够正确实现捕获回传事件。睿鑫网络Wu4R/h(|/_ M

睿鑫网络-M8A,e fv/ab

第三,实现事件属性结构。睿鑫网络B Ad$]1[t%FT

睿鑫网络 fP3mi YM9gg5N yFh

事件属性结构是一种优化的事件实现方式。在介绍之前,我们首先看看常见的控件事件实现方式。具体代码如下所示。

(u$W.Y^ O j0 睿鑫网络(W6ih:e\2b

......

ea}Vq|&vk0

)|z.[{h!Q*d}0B;ZX0public class WebCustomControl:WebControl,IPostBackEventHandler{

|s!s'E;tvwU2`E'V5K0

pe"P.Gx&_0 //声明Click事件委托

AaBFzB!n+n4R0

mc;u$a\&U%W6K@0 public event EventHandler Click;

V8w5v@4\1kV$?0 睿鑫网络 _9pzm eQCM

 //实现RaisePostBackEvent方法

0}#]FspDw0 睿鑫网络*h*W.jH*ak2AJ*K

 void IPostBackEventHandler.RaisePostBackEvent(string eventArgument) {

;b'C+L3G ^5f0

cgY7w2y/mG0  OnClick(EventArgs.Empty);

G,^oc%gN0

?)p.RxQa `!T0 }

:w`0?R(}9~ K0

!|7y#a7n@m0q Vt/u ~0 //定义OnClick事件处理程序

?-T(tD(\Qe0

~Bvy(V&aq0 protected virtual void OnClick(EventArgs e) {

t%a8D`U`/\Vg0

2Vc)[(Q,Z-c*G0  if(Click != null) { Click(this,e); }睿鑫网络+Jd0^aq a~

睿鑫网络~;q~c`.p.U

 }睿鑫网络8jn p!d5KP

w.GIMcDMl0 ......

W'C-eR y6}+M-q%`0 睿鑫网络-HF?1bV2qX S

}

+s)@8j8t T] y)K0

|M e6u2m.I9A0在以上代码中,包括了与事件定义相关的三个关键内容:一、定义Click事件委托;二、控件类实现了IPostBackEventHandler接口,其中当实现接口成员方法RaisePostBackEvent过程中,定义了事件处理程序OnClick;三、实现OnClick事件处理程序。以上实现方法简单易用,然而却存在一个缺点,即执行效率低。尤其是在一个类中引发多个事件的情况下,将会增加开销,浪费大量服务器资源,最终导致运行效率降低。

g,^fO,kBQKQ/@ Q+fw0 睿鑫网络[rjN7R;xo0V

为了解决以上问题,下面介绍一种优化的事件实现方式--事件属性结构。该结构使用System.ComponentModel.EventHandlerList类,这个类提供一个简单的委托列表。通过使用该类所提供的相关方法,开发人员能够灵活的操作控件的事件处理程序委托列表。例如,控件中的Click事件,使用事件属性结构如下:

~a2q C8Yz\0

7F%\(q"|P$G(cM0protected static readonly object EventClick = new object();

f/t&W-\O2O0

h7`b+mfo7Vp0public event EventHandler Click{

]_e$s:?.LeP x0

,JE IiKB kZ0 add {睿鑫网络H*[xZ/D

睿鑫网络#Sf-Ec2O&p#Q { u

  Events.AddHandler(EventClick,value);

|F0iKml0

C\4Vma0 }睿鑫网络[HbQ-x'W f\(`cZ

睿鑫网络 j+G\`%D3p"bA+e

 remove {

EC0G5FZNLw0 睿鑫网络(e h*D#bd:gO

  Events.RemoveHandler(EventClick,value);睿鑫网络O3Z0Hm(r |_"SJ9a

I;}7bX3Q0 }睿鑫网络o9^^|a |

睿鑫网络K[)}o)c6[

}

WZPxrF]0

`3pB T:r0在事件属性结构定义之前,首先需要定义Click事件委托对象。由于每个事件仅创建一次,因此,需要声明为静态和只读的。然后,在属性结构中通过AddHandler、RemoveHandler方法操作事件处理程序委托列表。当页面调用Click事件时,它向控件的EventHandlerList集合中添加或者删除处理程序。由于这种实现方法,在多个事件的声明过程中比普通的实现方法效率高,因此是非常值得推荐的方法。

8E Q P)Tb#j(Po0 睿鑫网络anu&u(~B&NMP#a

另外,在OnClick方法的实现过程中,当用一个事件属性时,必须从EventHandlerList中取回委托,并将其转换成EventHandler的类型。

#T6d6JHFq j a!LPD0

Z)x/ga0Lla0protected virtual void OnClick(EventArgs e){睿鑫网络"uBBabl J3s

睿鑫网络 H;\ Rjb)WwK

 EventHandler clickHandler = (EventHandler)Events[EventClick];睿鑫网络$j'jw(X D,[3[

o4@7H1u*]UJ0 if(clickHandler != null) {睿鑫网络F{z&R~

睿鑫网络Sll @{U/fO-l

clickHandler(this,e);睿鑫网络1}*c8n n7Z;qH

)?B~\p7Q:uX0 }

*?4O4n%CI cF:a |b0 睿鑫网络u^]5p [\(lq

}睿鑫网络0yc4a7F)o |+K

睿鑫网络 Ru@ F%@%F

请读者注意:事件属性结构不适用于VB.NET语言,只能在C#等语言中应用。

Ni h"O:q0 睿鑫网络J"w.?,la%v%w;H

2. 典型应用

)} Iw U iV4U0 睿鑫网络;yT t qr?F|

实事求是的讲,以上捕获回传事件的理论介绍对于从未实现过服务器控件事件的读者而言,有些难以理解。为此,本小节通过一个典型的示例来具体说明捕获回传事件的实现方法。

;M k` s)p0 睿鑫网络!|X9RC!y {R

本例实现了一个自定义服务器控件WebCustomControl。该控件虽然呈现为一个按钮外观,但是其并不是从Button类继承而来。当单击该按钮时,控件将引起回传,服务器端自动捕获回传的单击事件,并且引发Click事件,执行对应事件处理程序。下面是服务器控件实现的源代码代码:

G\*~*X%E\5\0 睿鑫网络A3W5~5S)G S$h;q(|*H

using System;

W%|%h:^!h {(T\0

&R4N'[b3Q Jr&wk0using System.Collections.Generic;睿鑫网络EC P+MNN\/x

睿鑫网络:GF `|[

using System.ComponentModel;

;Sm;]$x#Ao&g0 睿鑫网络5z3ShCt`#L

using System.Text;

p#G$].V$ng wl{x0

n)g,~a N0using System.Web;

3tYL]2qg"x@0

1?9e a]Q0using System.Web.UI;睿鑫网络wp Z5E Wag#F

`2|.@v{E"nZ0using System.Web.UI.WebControls;睿鑫网络"?sagY1g'\8k)\

睿鑫网络&A @ k tT"`

namespace WebControlLibrary{ [DefaultEvent("Click")]

3[1fw8o t |0 睿鑫网络)j0hz)^u

[ToolboxData("<{0}:WebCustomControl runat=server>")]

I Yo;x w*w0

"b6vv@U6i2d0public class WebCustomControl : WebControl, IPostBackEventHandler {睿鑫网络}%Y#^;o| R g X

T5yfo,VIW)L0 // 定义一个Click事件委托对象睿鑫网络Si(X$T"rTc;Nh

/Z1|D;s}r9M/y0 private static readonly object EventClick = new object();睿鑫网络 qH'fD a+Oc)ti-d

睿鑫网络pm t.pO0[z9N7J!Om

 //实现Click事件属性睿鑫网络t4y0bq o0`8k&H$kc F7lb

睿鑫网络\G2u&H4t/w

 [Description("Click事件属性"), Category("Action") ]

-|,f y;n%SEG/x0

&K/iC&e!K0 public event EventHandler Click {

};KI4dL9U5X:Xf0

s*`?&^.\KL9K0  add {

L!ZZ5aw7h,K0

N`A6e| AU0   Events.AddHandler(EventClick, value);

(M0~1EWh~+I*e0

{Au2`.O0  }

6a#go9mf,VN_0 睿鑫网络O1]G#j/nEC

  remove {

-[5aF5u/C(Uj,C0 睿鑫网络$N^(?1J)jk1xG2J

   Events.RemoveHandler(EventClick, value);

&X4XIhu0

_MTQ#Y9f*O%|6@0  }睿鑫网络7ODdo;E

睿鑫网络:D r},V4wyG@ F;A

 }睿鑫网络k)G,_,b b'\U

-p6Ux Y` Q?_ R ~0 

1D{ U\T(JvU9V0 睿鑫网络`UH I'f\9bi y"?

 // 重写控件呈现方法RenderContents睿鑫网络 _ E+h7`I*N3zC

S9It'M&ojx0 protected override void RenderContents(HtmlTextWriter output) {睿鑫网络:eh)GH)C^

0V D|I^0  output.Write("");睿鑫网络:K&`"o,S v-SN SMuso

@ |e%qp5D%dW q0 }

.T#[2pqj0 睿鑫网络y h/Ce2v

 //实现事件方法

,^8`J&N:J i0

Zu M_:hd*R/} i0 protected virtual void OnClick(EventArgs e) {

hVlV*TxVU1kt0

6IaR?+J5?`D0  EventHandler clickHandler = (EventHandler)Events[EventClick];

SG!rD.M0 睿鑫网络i(|:a(ycqq8H

  if (clickHandler != null) {

_2LkU)nl.J0

!Z r(h)re4K%M2m0   clickHandler(this, e);睿鑫网络.d5PP(Il-F5U'F

睿鑫网络uB[,h@

  }

[ WY4I x*qS0

?8E;`$e^D0 }

j(q0`F*Pee0 睿鑫网络1KYY|]6z

 // 实现IPostBackEventHandler接口成员

?)DOx | _`0

]9M?4s_?_2~/O*\0 void IPostBackEventHandler.RaisePostBackEvent(string eventArgument) {睿鑫网络,z/A.a)Y;hn8MWl

睿鑫网络s1A%W'U-Byy

  OnClick(EventArgs.Empty);

*@l]f!A`P&I d/y!I0

'?UO5Go?/cI0 }睿鑫网络)S2kf*cc

4{LH3}do&`0}

e8{%J*Jc_0

G$VR ^"H/E6t%b fp0}

"j.F W-\m&uP/T0

-JD6?w#x$A2je0在WebCustomControl类中,实现了以下有关捕获回传事件处理的关键内容:睿鑫网络9Ns&Srf9Xct

L*f,?:?-@ @+pkA0·控件类WebCustomControl实现IPostBackEventHandler;睿鑫网络#?K jd,u4e bEg

睿鑫网络e;N @r DDb

·将引发回传的控件的name属性值设置UniqueID;

"r8bi"~mlu0

'] McRWP9Rb0·实现事件属性结构,维护事件处理程序委托列表;睿鑫网络!YS!}'b RGX

^P?`V5`b0·在RaisePostBackEvent方法中调用OnClick方法;睿鑫网络EuY:E.D(Z9d's6_-{

0n!?IT n4dG0下面的代码是应用自定义按钮WebCustomControl的Default.aspx源代码,显示效果如图1和图2所示。睿鑫网络b(I~r{$g;J0I

睿鑫网络(M#|y&V-?P R8W1f5L'B

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>睿鑫网络5rv \]D GW&T @

7G"e/j3r:U"yc*U0<%@ Register TagPrefix="cc" Namespace="WebControlLibrary" Assembly="WebControlLibrary" %>睿鑫网络DJ$O}0f2Q

睿鑫网络2y(EAm3W(mL3U QG7~

睿鑫网络ZY[9n1W/\,Ni

睿鑫网络0X3_j6U@ y @']b

o tvEP`6p/?&x3r^7[0

3S{}3R,a] j.f0

'htDQD LQNZ0

%|I;v#P}4ua0

q+I Z,b4L0 睿鑫网络i8k"_{/M.W_

捕获回传事件

'K,o'jlk0

Z3_.XU(C9o0睿鑫网络)DJj0tb#^0W?

睿鑫网络n J`+[\%JzMr

睿鑫网络MW|w/l.j%dm

睿鑫网络fR5PLM/gW!].o

 

5?|+?$@{1m:b0

3` HG{+T4flR0 

8e8m+Y,JZc5W0 睿鑫网络*\a[5t;xa.y5l

  
~$K5A']%vT|0 睿鑫网络{Wmx5g[xCH

D+z~MY0

fg!c:m,{ss7r"k0  

-oxj8gj*ld \"l&g0

~h D6Sb,??B0 

睿鑫网络ioaSo Fw

睿鑫网络[+M6u.X*s"j)AA

_o!Zm1B:_Ht0

~'s1RI-G4Pt q0睿鑫网络RxIG,xW2L(\

睿鑫网络.Q&xH/d?*i

u \Iqa3?0 睿鑫网络GY+CB&q7v4_

下图1和图2是应用效果图。

PY+j:|4_B5|0 睿鑫网络M:L)`m3^E1q

睿鑫网络r*o7IO q

f:I`g l2v~le0图1 页面初始化效果图 图2 点击按钮后的效果图睿鑫网络y-h"\f B$U

睿鑫网络)ztm(M_1} V1S(['^

另外,还有一个与捕获回传事件密切相关的属性AutoPostBack。该属性用于控件的自动回传设置,很多标准的服务器控件中均包含该属性。对于开发人员来讲,是否需要在自行创建的服务器控件中定义该属性是很重要的,需要根据控件的功能需求认真考虑取舍。该属性的关键代码实现如下:睿鑫网络 Uvn+dQ \b#G2x

:Q*N6{i4z7R&H*u"i*Y0//定义属性AutoPostBack睿鑫网络z0JW*c)S,i-X

[T5k{8do5v Zx0public bool AutoPostBack{睿鑫网络+\4j&D6OU(T5OLU

+E(`FH"U0 set {

.]uVN DT0

-c yT4]*RfH0  this._autoPostBack = value;睿鑫网络8^V9~U4d)X

睿鑫网络0@`+fN%Rjj

 }

,~ \ ri"`0

6]Fq)xqN0 get {

8p#vO~)yuz0

!r6}x,[mZgp'{0  return this._autoPostBack;

dP'KO,c/K7_:u8sj6q0 睿鑫网络 rF}#b)x"Gy%G

 }睿鑫网络\|'b6p w&I0I

睿鑫网络U,SS@,B*i

}

j1R"@p)?%OO0 睿鑫网络qF%syY/{ ic-T5G

//在Render方法中添加Page.GetPostBackEventReference()方法

`r:S@)r0B g1m.z0

_!i&wY0Q Z0protected override void Render(HtmlTextWriter output){

R(uk R#n3[ XtCrU ~0

Ntp0{-sn?#Z%Fz0 ......睿鑫网络2ds9O [4O@+C+nyoW-J

^X#j,?g;[$q,J0 if(this.AutoPostBack) {

2w'X2NN|,W e0 睿鑫网络h\)MgG2pS[8j

  writer.WriteAttribute("ontextchanged","javascript:" + Page.GetPostBackEventReference(this));睿鑫网络9Py0\3Kp.K+N

u mMo Lv ufM0 }

E'h"L'Q]:r0 睿鑫网络hZbxDr"}

 ......睿鑫网络r2i)] ~*M;~jP d

睿鑫网络nb,j7e\ Fg

}睿鑫网络yZ*fC;V;W

睿鑫网络 g`Jfa c`

由以上代码可知,AutoPostBack属性的实现重点是Page.GetPostBackEventReference方法的应用。该方法获取对客户端脚本函数的引用,调用该函数将使服务器发送回该页,并返回一段表示客户端事件的字符串,实际是一些客户端代码。当AutoPostBack="true"时,服务器控件将发生自动回传,而不需通过Click事件等引发;当AutoPostBack="false",则回传必须经过类似Click的事件引发。

!g4{SUtf:R0 睿鑫网络,PBH8I$~rSi }!d

以上介绍的是有关捕获回传事件的具体实现方法。总体来讲不是非常复杂,然而,实现捕获回传事件的具体应用非常灵活,远远没有这么简单,这就需要读者不断的实践才能深入理解。

phA8@6b5uF B0

Jc!|6@)]*r#Z}03. 小结睿鑫网络%Ph o\\7Kz\

睿鑫网络t }{\lS-F

本文首先介绍了利用ASP.NET 2.0技术,为自定义服务器控件实现捕获回传事件的实现方法。通过这些内容,相信读者可以基本掌握实现控件捕获回传事件的方法。在随后的文章中,笔者将继续介绍实现事件处理的另一核心内容--处理回传数据。

(O#{FRLK)q _0
上一篇 下一篇

网络资源