This series comes from: http://www.chinaitz.com/html/2009/0307/398749.html
Now, we have developed a control before. The property is also added, and the development is also very standard, but the control is still the last point: add events.
ASP. NET development is event-driven. Now let's add events to the control. Before talking about events, I hope you will be familiar with the C # syntax and be familiar with delegation events.
In fact, the procedure for defining an event is simple:
1. Declare a delegate.
2. Define a class that carries event information.
3. Define events 4. define the methods for notifying other objects after a communication event occurs. First, clarify our ideas:
1. Select a value from the drop-down list and enter a value in the input box.
2. Click the submit button on the page to trigger a Custom Event validate (verify that the input information is correct ).
We need to transmit the control information to the server during submission. Therefore, we need to define an event information class to deliver the information class to the server when an event occurs.
The event is defined as follows:
1. Define a class carrying event information.
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. Declare a delegate.
1usingSystem;
2usingSystem.Collections.Generic;
3usingSystem.Text;
4
5namespaceCreditCardForm
6{
7 publicdelegatevoidValidateCreditCardFormEventHandler(objectsender,ValidateCreditCardFormEventArgsargs);
8}
9
3. Define events
1 publiceventValidateCreditCardFormEventHandlerValidateCreditCardForm;
4. Methods for notifying other objects after an event occurs
1
2 // This method is a protected virtual Method
3 protectedvoidonvalidatecreditcardform (validatecreditcardformeventargsargs)
4 {
5 If (validatecreditcardform! = NULL)
6 handler (this, argS );
7}
After these steps, the control event is completed. Try it!
In the previous article, we only briefly talked about events, but we should use methods to define events simply in ASP. NET custom controls. If you develop events in winform, there may be no major problems with the previous definition, but the efficiency method is not considered and can still be run.
Next we will return to the event in ASP. NET.
You may have read the previously defined events. Indeed, the events are generally defined in that way, but after the events are defined in that way, the running efficiency is not involved, because after the events are defined in that way, when compiling Event code, the compiler automatically adds a lot of multi-threaded security code to us, that is, although we only define several lines of code, large, but the compiler has done a lot of extra things for us. Of course, the efficiency of code execution can be imagined.
In many cases, we do not need to consider the multi-thread security issue for custom control events, so we need to change the code to make it run better. We will adopt the following method: the displayed declarative event:
1
2 // actually, it is an auxiliary variable used as the "key" in hashtable.
3 privatestaticobjectvalidatecreditcardformkey = 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}
Note: In fact, for the code of the previously defined event, when the compiler compiles our code, it is also compiled into the above form and some additional security control code is added, here, we do not want the compiler to generate it, But we write it ourselves, which is highly efficient.
Also, if an event has been registered in the event list (A hashtable), when there are two custom controls on the page that are the same, the events of my control are only registered once, high efficiency.
An event is defined here. The current task is to trigger the event. That is, click "Submit" to trigger. Let's first understand the process:
Click Submit. The entire page is submitted to the server, and the lifecycle of the page starts.
1. parse the page and set the source in the original page, as shown in <asp:...> </asp> the tag is parsed into the corresponding HTML code. After the page is parsed, the page is the HTML style on the server. (I am very rough about it here, and there is no need to make it so detailed ).
2. after resolution, the page starts to check which control triggered the server to return, that is, after clicking the button, the whole page is submitted to the server, here is the "Submit" button.
3. On the resolved page, check whether the name of the "Submit" button is the same as the name of the control (creditcardform. Check whether the control creditcardform implements the ipostbackeventhandler interface. If it is implemented, the previously defined events will be triggered.
In this way, our controls are no different from the real server controls. (Note: The above 3rd point: the name of the button we want is the same as the name of creditcardform. The name here cannot be set manually by ourselves, because the creditcardform name is set on a page, the page sets it to: This. uniqueid, so we can only set the button name to this. uniqueid, so we can), so we need to rewrite some attributes of creditcardform5:
1 protectedoverridestringSubmitButtonName
2 {
3 get
4 {
5 returnthis.UniqueID;
6 }
7 }
Also, after each page is submitted to the server, this. uniqueid of the parsing page is different. In addition, if there are two creditcardforms on the same page, we also need to ensure that the other controls of the two controls, such as input boxes, have different names, so we need to rewrite the names respectively.
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 }
Now, we only need to implement the ipostbackeventhandler interface to call our events and implement the ipostbackeventhandler interface. There is actually only one method. The Code is also very simple:
1
2
3 // you can see that we just moved the previous Event Notification code here.
4voidipostbackeventhandler. raisepostbackevent (stringargs)
5 {
6 validatecreditcardformeventargsve = newvalidatecreditcardformeventargs (
7 paymentmethodtext, creditcardnotext, cardholdernametext, expirationdatetext );
8
9 onvalidatecreditcardform (VE );
10}
In this way, our control can cause the server to return a message, that is, when you click the "Submit" button, there will be a refreshing progress bar under the browser's status bar.
Note: there is another problem. We can indeed make our controls submit information to the server. But how can the server obtain the submitted information?
It's not that we leave everything alone after submitting the information to the server, and then the server will "Be obedient" for verification. This is not the case. At least we have to tell the server what information we have submitted to be verified.
The server receives our information in this way. It is easy to implement an interface-ipostbackdatahandler.
The interface has two methods. The first method is the loadpostdata method, which is to obtain our information and determine whether the information we submitted this time has changed or not.
The above method returns a Boolean value. If true is returned, the next method raisepostdatachangedevent is automatically called. You can see their functions in English.
Here we will only talk about the loadpostdata method. The method is written as follows:
1boolLoadPostData(stringpostDataKey,NameValueCollectionvalues)
2{
3
4}
Do not be afraid to see the method. You just need to look at the following parameters for the method parameter and the previous parameter.
The submission of our information is all written in the corresponding input box, drop-down box, and passed to the server. It is actually a key-value pair.
Key: the name of the input box, such as name.
Value: indicates the input value.
In fact, namevaluecollection is a hash table to store key-value pairs.
All the previous input information is included as a namevaluecollection and uploaded to the server. Then, the server obtains the value through the corresponding "key" (name) and then verifies it.
The Code is as follows:
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 }
In this way, we have finished writing the entire control. I don't know if you understand it. Please reply to the question! The complete code is as follows:
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