您的位置:首页 > 编程语言 > ASP

ASP.NET自定义控件组件开发 第三章 为控件添加事件

2009-04-24 11:40 447 查看
本系列来自:http://www.chinaitz.com/html/2009/0307/398749.html

好了,我们之前以前开发一个控件。而且也添加了属性,开发也很规范,但是那个控件还差最后一点:添加事件。

  ASP.NET的开发都是事件驱动的,现在我们就来为控件添加事件。在说事件之前,希望大家对C#的语法要熟悉,对委托很事件要懂。

  其实定义事件的步骤很简单:

  1.声明一个委托。

  2.定义一个携带事件信息的类。

  3.定义事件4.定义一个通事件发生后,通知其他对象的方法首先来理清一下我们的思路:

  1.在下拉框中选中一个值,并且在输入框中也输入相应的值。

  2.我们在页面点击“提交”按钮,按钮就触发我们自定义的一个事件Validate(验证输入信息的正确行)。

  我们在提交的时候要把控件的信息传给服务器,所以我们要定义一个事件信息类,来携带事件发生时,把个信息类送到服务器。

  事件定义如下:

  1.定义一个携带事件信息的类。

1usingSystem;
2usingSystem.Collections.Generic;
3usingSystem.Text;
4
5namespaceCreditCardForm
6{
7  publicclassValidateCreditCardFormEventArgs:EventArgs
8  {
9    privatestringpaymentMethod;
10    publicstringPaymentMethod
11    {
12      get
13      {
14        returnthis.paymentMethod;
15      }
16    }
17
18
19    privatestringcreditCardNo;
20    publicstringCreditCardNo
21    {
22      get
23      {
24        returnthis.creditCardNo;
25      }
26    }
27
28
29    privatestringcardholderName;
30    publicstringCardholderName
31    {
32      get
33      {
34        returnthis.cardholderName;
35      }
36    }
37
38    privateDateTimeexpirationDate;
39    publicDateTimeExpirationDate
40    {
41      get
42      {
43        returnthis.expirationDate;
44      }
45    }
46
47
48    publicValidateCreditCardFormEventArgs(stringpaymentmenthod,stringcreditcardno,
49      stringcardholdername,DateTimeexpirationdate)
50    {
51      this.paymentMethod=paymentmenthod;
52      this.creditCardNo=creditcardno;
53      this.cardholderName=cardholdername;
54      this.expirationDate=expirationdate;
55    }
56  }
57}
58


  2.声明一个委托。

1usingSystem;
2usingSystem.Collections.Generic;
3usingSystem.Text;
4
5namespaceCreditCardForm
6{
7  publicdelegatevoidValidateCreditCardFormEventHandler(objectsender,ValidateCreditCardFormEventArgsargs);
8}
9


  3.定义事件

1 publiceventValidateCreditCardFormEventHandlerValidateCreditCardForm;


  4.通事件发生后,通知其他对象的方法

1 
2//这个方法是受保护的虚方法
3protectedvoidOnValidateCreditCardForm(ValidateCreditCardFormEventArgsargs)
4    {
5       if(ValidateCreditCardForm!=null)
6        handler(this,args);
7    }


  这样几个步骤之后,控件的事件就写完了。大家试试!

 前一篇文章只是简单的说了下事件,但是大家应该方法,在ASP.NET自定义控件中只是简单那么定义事件是行不通。如果大家开发的是WinForm中的事件,之前的定义可能没有什么大的问题,只是在效率方法欠考虑而且,还是可以运行的。

  下面我们就回到ASP.NET中的事件。

  大家也许看了我们之前定义的事件,确实,事件一般是那么定义的,但是那样定义事件后的,运行起来的效率不搞,因为那样定义事件后,编译器在编译事件代码的时候,会自动的为我们加入很多多线程安全的代码,就是说,虽然我们只是定义几行代码,大但是编译器为我们做了很多额外的事情,当然,这样代码的运行的效率可想而知。

  在很多的时候,我们自定义控件的事件不是需要考虑多线程安全等问题的,所我们就要改变代码,使其运行的更加好,我们就采用下面的方法:显示的申明事件:

1 
2//其实其实一个辅助的变量,用来做Hashtable中的”键“
3privatestaticobjectValidateCreditCardFormKey=newobject();
4    publiceventValidateCreditCardFormEventHandlerValidateCreditCardForm
5    {
6      add
7      {
8        Events.AddHandler(ValidateCreditCardFormKey,value);
9      }
10      remove
11      {
12        Events.RemoveHandler(ValidateCreditCardFormKey,value);
13      }
14    }
15
16    
17    protectedvoidOnValidateCreditCardForm(ValidateCreditCardFormEventArgsargs)
18    {
19      ValidateCreditCardFormEventHandlerhandler=Events[ValidateCreditCardFormKey]
20                                    asValidateCreditCardFormEventHandler;
21      if(handler!=null)
22        handler(this,args);
23    }


注意:其实就我们之前定义的事件的代码而言,编译器在在编译我们的代码的时候,也是编译成了上面的形式而且还额外的加上了一些安全的控制代码,这里,我们现在不要编译器生成,而是我们自己写出来,效率就高了。


  还有就是:如果一个事件在事件列表(是一个hashtable)已经注册了,当页面上有两个相同我们自定义控件,我的控件的事件也只是在注册一次,效率也高了。

  到这里一个事件就定义好了。现在做的事情就是要触发事件。即,点击“提交”按钮,就触发。我们先了理解一下流程:

  点击“提交”,整个页面就向服务器提交了,之后就开始了页面的生命周期。

  1.对页面进行解析,将原来页面中的源,如<asp:....></asp>这样的标记解析成相应的html代码,当把页面解析完之后,页面在服务器就是html的样式了。(我这里说的很粗略,没有必要说的那么详细)。

  2.解析后的页面就开始检查,刚才是哪个控件引发的服务器回传,即,是点击了哪个按钮后,整个页面向服务器提交的,我们这里就是那个“提交”按钮。

  3.解析后的页面检查“提交”按钮的name是否和控件(CreditCardForm)的name相同,如果相同。再检查控件 CreditCardForm实现了IPostBackEventHandler接口,如果实现了,就引发我们之前定义的事件。

  这样,我们的控件就和真正的服务器控件没有两样了。(注意:上面的第3点:我们要按钮的name和CreditCardForm的name一样,这里的name我们无法用自己手动来设置他们的一样,因为CreditCardForm的名字是有页面来设置的,页面将其设置为:this.UniqueID,所以我们只能将按钮的名字设置为this.UniqueID,这样就可以了),所以我们要重写CreditCardForm5的一些属性:

1 protectedoverridestringSubmitButtonName
2    {
3      get
4      {
5        returnthis.UniqueID;
6      }
7    }


  还有,每一次页面提交给服务器后,解析页面的this.UniqueID都不一样。而且,如果在页面中同时有两个CreditCardForm,我们也要保证两个控件的其他控件,如输入框等等的name也不一样,所以要分别重写name。

1protectedoverridestringPaymentMethodListName
2    {
3      get
4      {
5        returnthis.UniqueID+":PaymentMethod";
6      }
7    }
8
9    protectedoverridestringCreditCardNoTextName
10    {
11      get
12      {
13        returnthis.UniqueID+":CreditCardNo";
14      }
15    }
16
17    protectedoverridestringCardholderNameTextName
18    {
19      get
20      {
21        returnthis.UniqueID+":CardholderName";
22      }
23    }
24
25    protectedoverridestringMonthListName
26    {
27      get
28      {
29        returnthis.UniqueID+":Month";
30      }
31    }
32
33    protectedoverridestringYearListName
34    {
35      get
36      {
37        returnthis.UniqueID+":Year";
38      }
39    }


这里以后,下面我们就只要实现IPostBackEventHandler接口,就可以调用我们的事件了,实现IPostBackEventHandler接口,其实只有一个方法。而且也很简单,代码:


1 
2
3//大家看看我们只是将之前的事件通知代码移到了这里。
4voidIPostBackEventHandler.RaisePostBackEvent(stringargs)
5    {
6      ValidateCreditCardFormEventArgsve=newValidateCreditCardFormEventArgs(
7        PaymentMethodText,CreditCardNoText,CardholderNameText,ExpirationDateText);
8
9      OnValidateCreditCardForm(ve);
10    }


  这样以后,我们的控件就可以引发服务器回传了,即,当你点击“提交”按钮时,我们的浏览器的状态栏下面就有刷新的进度条了。

  注意,还有一个问题啊,我们确实能够使得我们的控件向服务器提交信息,但是服务器怎么来得到我们的提交的信息呢?

  并不是我们把信息向服务器提交后,就什么都不管了,然后服务器就”很听话的“进行验证。不是这样的,起码我们还要告诉服务器,我们提交了哪些要被验证的信息。

  那么服务器这样接受到我们的信息,,很简单,只要实现一个接口就可以了--IPostBackDataHandler。

  接口有两个方法,第一个就是LoadPostData方法,就是来获取我们的信息,并且判断我们这次提交的信息和上次有变化没有。

  上面的方法返回一个布尔的值,如果返回true,就自动的调用下一个方法RaisePostDataChangedEvent,大家可以根据方法的英文看到他们的作用。

  这里我们只是讲下LoadPostData方法,方法的完成写法是这样的:

1boolLoadPostData(stringpostDataKey,NameValueCollectionvalues)
2{
3
4}


  看见方法不要害怕,方法的参数,前一个参数,我们不要管,只要看看后面的参数就可以了。

  我们的信息的提交,都是在相应的输入框,下拉框中写好了,传给服务器的,其实是以:键值对,传了的.

  键:就是我们输入框等的名字,name

  值:就是输入的值。

  其实NameValueCollection就是一个哈希表,来存放键值对的。

  我们之前的所有输入的信息被包含成了一个NameValueCollection传到服务器,然后服务器就通过对应的“键”(name)来获取值,然后验证。

  代码如下:

1 boolIPostBackDataHandler.LoadPostData(stringpostDataKey,NameValueCollectionvalues)
2    {
3      stringpaymentMethod=values[PaymentMethodListName]=="0"?"Master":"Visa";
4      if(paymentMethod!=PaymentMethodText)
5      {
6        PaymentMethod=paymentMethod;
7        hasPaymentMethodChanged=true;
8      }
9
10      stringcreditCardNo=values[CreditCardNoTextName];
11      if(creditCardNo!=CreditCardNoText)
12      {
13        CreditCardNoText=creditCardNo;
14        hasCreditCardNoChanged=true;
15      }
16
17      stringcardholderName=values[CardholderNameTextName];
18      if(cardholderName!=CardholderNameText)
19      {
20        CardholderNameText=cardholderName;
21        hasCardholderNameChanged=true;
22      }
23
24      intmonth=int.Parse(values[MonthListName]);
25      intyear=int.Parse(values[YearListName]);
26      DateTimeexpirationDate=newDateTime(year,month,10);
27      if(expirationDate!=ExpirationDateText)
28      {
29        ExpirationDateText=expirationDate;
30        hasExpirationDateChanged=true;
31      }
32
33
34      if(!string.IsNullOrEmpty(values[SubmitButtonName]))
35        Page.RegisterRequiresRaiseEvent(this);
36
37      returnhasExpirationDateChanged||
38        hasCreditCardNoChanged||
39        hasPaymentMethodChanged||
40        hasCardholderNameChanged;
41
42    }


这样,我们整个控件就写完了,不知道大家懂了没:有问题回复!完整代码如下:


 1usingSystem;
 2usingSystem.Collections.Generic;
 3usingSystem.Text;
 4usingSystem.Web;
 5usingSystem.Web.UI;
 6usingSystem.Web.UI.WebControls;
 7usingSystem.Collections;
 8
 9usingSystem.Collections.Specialized;
10
11namespaceCreditCardForm
12{
13  publicclassCreditCardForm6:CreditCardForm5,IPostBackEventHandler,IPostBackDataHandler
14  {
15    #regionoverridename
16    protectedoverridestringPaymentMethodListName
17    {
18      get
19      {
20        returnthis.UniqueID+":PaymentMethod";
21      }
22    }
23
24    protectedoverridestringCreditCardNoTextName
25    {
26      get
27      {
28        returnthis.UniqueID+":CreditCardNo";
29      }
30    }
31
32    protectedoverridestringCardholderNameTextName
33    {
34      get
35      {
36        returnthis.UniqueID+":CardholderName";
37      }
38    }
39
40    protectedoverridestringMonthListName
41    {
42      get
43      {
44        returnthis.UniqueID+":Month";
45      }
46    }
47
48    protectedoverridestringYearListName
49    {
50      get
51      {
52        returnthis.UniqueID+":Year";
53      }
54    }
55
56    protectedoverridestringSubmitButtonName
57    {
58      get
59      {
60        returnthis.UniqueID;
61      }
62    }
63    #endregion
64    #regionprorerty
65
66    publicstringPaymentMethodText
67    {
68      get
69      {
70        returnViewState["PaymentMethod"]!=null?(string)ViewState["PaymentMethod"]:string.Empty;
71      }
72      set
73      {
74        ViewState["PaymentMethod"]=value;
75      }
76    }
77
78
79    publicstringCreditCardNoText
80    {
81      get
82      {
83        returnViewState["CreditCardNo"]!=null?(string)ViewState["CreditCardNo"]:string.Empty;
84      }
85      set
86      {
87        ViewState["CreditCardNo"]=value;
88      }
89    }
90
91    publicstringCardholderNameText
92    {
93      get
94      {
95        returnViewState["CardholderName"]!=null?(string)ViewState["CardholderName"]:string.Empty;
96      }
97      set
98      {
99        ViewState["CardholderName"]=value;
100      }
101    }
102
103    publicDateTimeExpirationDateText
104    {
105      get
106      {
107        returnViewState["ExpirationDate"]!=null?(DateTime)ViewState["ExpirationDate"]:DateTime.Now;
108      }
109      set
110      {
111        ViewState["ExpirationDate"]=value;
112      }
113    }
114
115
116    #endregion
117
118    #regionevents
119    privatestaticobjectValidateCreditCardFormKey=newobject();
120    publiceventValidateCreditCardFormEventHandlerValidateCreditCardForm
121    {
122      add
123      {
124        Events.AddHandler(ValidateCreditCardFormKey,value);
125      }
126      remove
127      {
128        Events.RemoveHandler(ValidateCreditCardFormKey,value);
129      }
130    }
131
132    
133    protectedvoidOnValidateCreditCardForm(ValidateCreditCardFormEventArgsargs)
134    {
135      ValidateCreditCardFormEventHandlerhandler=Events[ValidateCreditCardFormKey]
136                                    asValidateCreditCardFormEventHandler;
137      if(handler!=null)
138        handler(this,args);
139    }
140
141    #endregion
142    voidIPostBackEventHandler.RaisePostBackEvent(stringargs)
143    {
144      ValidateCreditCardFormEventArgsve=newValidateCreditCardFormEventArgs(
145        PaymentMethodText,CreditCardNoText,CardholderNameText,ExpirationDateText);
146
147      OnValidateCreditCardForm(ve);
148    }
149
150    privateboolhasPaymentMethodChanged;
151    privateboolhasCreditCardNoChanged;
152    privateboolhasCardholderNameChanged;
153    privateboolhasExpirationDateChanged;
154
155    boolIPostBackDataHandler.LoadPostData(stringpostDataKey,NameValueCollectionvalues)
156    {
157      stringpaymentMethod=values[PaymentMethodListName]=="0"?"Master":"Visa";
158      if(paymentMethod!=PaymentMethodText)
159      {
160        PaymentMethod=paymentMethod;
161        hasPaymentMethodChanged=true;
162      }
163
164      stringcreditCardNo=values[CreditCardNoTextName];
165      if(creditCardNo!=CreditCardNoText)
166      {
167        CreditCardNoText=creditCardNo;
168        hasCreditCardNoChanged=true;
169      }
170
171      stringcardholderName=values[CardholderNameTextName];
172      if(cardholderName!=CardholderNameText)
173      {
174        CardholderNameText=cardholderName;
175        hasCardholderNameChanged=true;
176      }
177
178      intmonth=int.Parse(values[MonthListName]);
179      intyear=int.Parse(values[YearListName]);
180      DateTimeexpirationDate=newDateTime(year,month,10);
181      if(expirationDate!=ExpirationDateText)
182      {
183        ExpirationDateText=expirationDate;
184        hasExpirationDateChanged=true;
185      }
186
187
188      if(!string.IsNullOrEmpty(values[SubmitButtonName]))
189        Page.RegisterRequiresRaiseEvent(this);
190
191      returnhasExpirationDateChanged||
192        hasCreditCardNoChanged||
193        hasPaymentMethodChanged||
194        hasCardholderNameChanged;
195
196    }
197
198    voidIPostBackDataHandler.RaisePostDataChangedEvent()
199    {
200      boolhasChanged;
201      hasChanged=hasCardholderNameChanged||
202        hasCreditCardNoChanged||
203        hasPaymentMethodChanged||
204        hasExpirationDateChanged;
205
206      if(hasChanged)
207      {
208
209        ValidateCreditCardFormEventArgsargs=newValidateCreditCardFormEventArgs(
210          PaymentMethod,CreditCardNoText,CardholderNameText,ExpirationDateText);
211
212        OnValidateCreditCardForm(args);
213      }
214    }
215
216  }
217}
218
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐