ASP.NET自定义控件组件开发 第三章 为控件添加事件 后篇
?????????????????????????????????????????????????? 第三章 為控件添加事件 后篇
?
?????????? 前一篇文章只是簡單的說了下事件,但是大家應該方法,在ASP.NET自定義控件中只是簡單那么定義事件是行不
通。如果大家開發的是WinForm中的事件,之前的定義可能沒有什么大的問題,只是在效率方法欠考慮而且,還是可以運行
的。
?
系列文章鏈接:
ASP.NET自定義控件組件開發 第一章 待續
ASP.NET自定義控件組件開發 第一章 第二篇 接著待續
ASP.NET自定義控件組件開發 第一章 第三篇
ASP.NET自定義控件組件開發 第二章 繼承WebControl的自定義控件
ASP.NET自定義控件組件開發 第三章 為控件添加事件 前篇
ASP.NET自定義控件組件開發 第三章 為控件添加事件 后篇
ASP.NET自定義控件組件開發 第四章 組合控件開發CompositeControl
ASP.NET自定義控件組件開發 第四章 組合控件開發CompositeControl 后篇 --事件冒泡
ASP.NET自定義控件組件開發 第五章 模板控件開發
ASP.NET2.0自定義控件組件開發 第六章 深入講解控件的屬性
ASP.NET2.0組件控件開發視頻 初體驗
??????????下面我們就回到ASP.NET中的事件。
?
??????????大家也許看了我們之前定義的事件,確實,事件一般是那么定義的,但是那樣定義事件后的,運行起來的效率不搞,
?
因為那樣定義事件后,編譯器在編譯事件代碼的時候,會自動的為我們加入很多多線程安全的代碼,就是說,雖然我們只是
?
定義幾行代碼,大但是編譯器為我們做了很多額外的事情,當然,這樣代碼的運行的效率可想而知。
?
?????在很多的時候,我們自定義控件的事件不是需要考慮多線程安全等問題的,所我們就要改變代碼,使其運行的更加好,
?
我們就采用下面的方法:顯示的申明事件:
?
?
?
?
Code?1??
?2?//其實其實一個輔助的變量,用來做Hashtable中的”鍵“
?3?private?static?object?ValidateCreditCardFormKey?=?new?object();
?4?????????public?event?ValidateCreditCardFormEventHandler?ValidateCreditCardForm
?5?????????{
?6?????????????add
?7?????????????{
?8?????????????????Events.AddHandler(ValidateCreditCardFormKey,?value);
?9?????????????}
10?????????????remove
11?????????????{
12?????????????????Events.RemoveHandler(ValidateCreditCardFormKey,?value);
13?????????????}
14?????????}
15?
16????????
17?????????protected?void?OnValidateCreditCardForm(ValidateCreditCardFormEventArgs?args)
18?????????{
19?????????????ValidateCreditCardFormEventHandler?handler?=?Events[ValidateCreditCardFormKey]
20?????????????????????????????????????????????????????????????????????????as?ValidateCreditCardFormEventHandler;
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的一些屬性:
?
?????
Code1??protected?override?string?SubmitButtonName
2?????????{
3?????????????get
4?????????????{
5?????????????????return?this.UniqueID?;
6?????????????}
7?????????}
?
??????????還有,每一次頁面提交給服務器后,解析頁面的this.UniqueID都不一樣。而且,如果在頁面中同時有兩個CreditCardForm,我們也要保證兩個控件的其他控件,如輸入框等等的name也不一樣,所以要分別重寫name。
?????
Code?1?protected?override?string?PaymentMethodListName
?2?????????{
?3?????????????get
?4?????????????{
?5?????????????????return?this.UniqueID?+?":PaymentMethod";
?6?????????????}
?7?????????}
?8?
?9?????????protected?override?string?CreditCardNoTextName
10?????????{
11?????????????get
12?????????????{
13?????????????????return?this.UniqueID?+?":CreditCardNo";
14?????????????}
15?????????}
16?
17?????????protected?override?string?CardholderNameTextName
18?????????{
19?????????????get
20?????????????{
21?????????????????return?this.UniqueID?+?":CardholderName";
22?????????????}
23?????????}
24?
25?????????protected?override?string?MonthListName
26?????????{
27?????????????get
28?????????????{
29?????????????????return?this.UniqueID?+":Month";
30?????????????}
31?????????}
32?
33?????????protected?override?string?YearListName
34?????????{
35?????????????get
36?????????????{
37?????????????????return?this.UniqueID?+?":Year";
38?????????????}
39?????????}
?
??????????這里以后,下面我們就只要實現IPostBackEventHandler接口,就可以調用我們的事件了,實現IPostBackEventHandler接口,其實只有一個方法。而且也很簡單,代碼:
?
?????
Code?1??
?2?
?3?//大家看看我們只是將之前的事件通知代碼移到了這里。
?4?void?IPostBackEventHandler.RaisePostBackEvent(string?args)
?5?????????{
?6?????????????ValidateCreditCardFormEventArgs?ve?=?new?ValidateCreditCardFormEventArgs(
?7?????????????????PaymentMethodText,?CreditCardNoText,?CardholderNameText,?ExpirationDateText);
?8?
?9?????????????OnValidateCreditCardForm(ve);
10?????????}
?
?
?????這樣以后,我們的控件就可以引發服務器回傳了,即,當你點擊“提交”按鈕時,我們的瀏覽器的狀態欄下面就有刷新的
?
進度條了。
?
??????????注意,還有一個問題啊,我們確實能夠使得我們的控件向服務器提交信息,但是服務器怎么來得到我們的提交的信息
?
呢?
?
?????并不是我們把信息向服務器提交后,就什么都不管了,然后服務器就”很聽話的“進行驗證。不是這樣的,起碼我們還要
?
告訴服務器,我們提交了哪些要被驗證的信息。
?
?????那么服務器這樣接受到我們的信息,,很簡單,只要實現一個接口就可以了--IPostBackDataHandler。
?
?????接口有兩個方法,第一個就是LoadPostData方法,就是來獲取我們的信息,并且判斷我們這次提交的信息和上次有變化
?
沒有。
?
?????上面的方法返回一個布爾的值,如果返回true,就自動的調用下一個方法RaisePostDataChangedEvent,
?
?????大家可以根據方法的英文看到他們的作用。
?
???????這里我們只是講下LoadPostData方法,方法的完成寫法是這樣的:
?????
Code1?bool?LoadPostData(string?postDataKey,?NameValueCollection?values)
2?{
3?
4?}
?
?
?
?
?
?
?????看見方法不要害怕,方法的參數,前一個參數,我們不要管,只要看看后面的參數就可以了。
?????
?????我們的信息的提交,都是在相應的輸入框,下拉框中寫好了,傳給服務器的,其實是以:鍵值對,傳了的.
?????
?????鍵:就是我們輸入框等的名字,name
?????值:就是輸入的值。
?
?????其實NameValueCollection就是一個哈希表,來存放鍵值對的。
?
?????我們之前的所有輸入的信息被包含成了一個NameValueCollection傳到服務器,然后服務器就通過對應的“鍵”(name)來獲取值,然后驗證。
?
?
?
?????代碼如下:
?
Code?1??bool?IPostBackDataHandler.LoadPostData(string?postDataKey,?NameValueCollection?values)
?2?????????{
?3?????????????string?paymentMethod?=?values[PaymentMethodListName]?==?"0"???"Master"?:?"Visa";
?4?????????????if?(paymentMethod?!=?PaymentMethodText)
?5?????????????{
?6?????????????????PaymentMethod?=?paymentMethod;
?7?????????????????hasPaymentMethodChanged?=?true;
?8?????????????}
?9?
10?????????????string?creditCardNo?=?values[CreditCardNoTextName];
11?????????????if?(creditCardNo?!=?CreditCardNoText)
12?????????????{
13?????????????????CreditCardNoText?=?creditCardNo;
14?????????????????hasCreditCardNoChanged?=?true;
15?????????????}
16?
17?????????????string?cardholderName?=?values[CardholderNameTextName];
18?????????????if?(cardholderName?!=?CardholderNameText)
19?????????????{
20?????????????????CardholderNameText?=?cardholderName;
21?????????????????hasCardholderNameChanged?=?true;
22?????????????}
23?
24?????????????int?month?=?int.Parse(values[MonthListName]);
25?????????????int?year=int.Parse?(values?[YearListName?]);
26?????????????DateTime?expirationDate=new?DateTime?(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?????????????return?hasExpirationDateChanged||
38?????????????????hasCreditCardNoChanged?||
39?????????????????hasPaymentMethodChanged?||
40?????????????????hasCardholderNameChanged?;
41?
42?????????}
?
?
?
?????這樣,我們整個控件就寫完了,不知道大家懂了沒:有問題回復!完整代碼如下:
?????
Code??1?using?System;
??2?using?System.Collections.Generic;
??3?using?System.Text;
??4?using?System.Web;
??5?using?System.Web.UI;
??6?using?System.Web.UI.WebControls;
??7?using?System.Collections?;
??8?
??9?using?System.Collections.Specialized?;
?10?
?11?namespace?CreditCardForm
?12?{
?13?????public?class?CreditCardForm6:CreditCardForm5?,IPostBackEventHandler,IPostBackDataHandler
?14?????{
?15?????????#region?override?name
?16?????????protected?override?string?PaymentMethodListName
?17?????????{
?18?????????????get
?19?????????????{
?20?????????????????return?this.UniqueID?+?":PaymentMethod";
?21?????????????}
?22?????????}
?23?
?24?????????protected?override?string?CreditCardNoTextName
?25?????????{
?26?????????????get
?27?????????????{
?28?????????????????return?this.UniqueID?+?":CreditCardNo";
?29?????????????}
?30?????????}
?31?
?32?????????protected?override?string?CardholderNameTextName
?33?????????{
?34?????????????get
?35?????????????{
?36?????????????????return?this.UniqueID?+?":CardholderName";
?37?????????????}
?38?????????}
?39?
?40?????????protected?override?string?MonthListName
?41?????????{
?42?????????????get
?43?????????????{
?44?????????????????return?this.UniqueID?+":Month";
?45?????????????}
?46?????????}
?47?
?48?????????protected?override?string?YearListName
?49?????????{
?50?????????????get
?51?????????????{
?52?????????????????return?this.UniqueID?+?":Year";
?53?????????????}
?54?????????}
?55?
?56?????????protected?override?string?SubmitButtonName
?57?????????{
?58?????????????get
?59?????????????{
?60?????????????????return?this.UniqueID?;
?61?????????????}
?62?????????}
?63?????????#endregion
?64?????????#region?prorerty
?65?
?66?????????public?string?PaymentMethodText
?67?????????{
?68?????????????get
?69?????????????{
?70?????????????????return?ViewState["PaymentMethod"]?!=?null???(string)ViewState["PaymentMethod"]?:?string.Empty?;
?71?????????????}
?72?????????????set
?73?????????????{
?74?????????????????ViewState["PaymentMethod"]?=?value;
?75?????????????}
?76?????????}
?77?
?78?
?79?????????public?string?CreditCardNoText
?80?????????{
?81?????????????get
?82?????????????{
?83?????????????????return?ViewState["CreditCardNo"]?!=?null???(string)ViewState["CreditCardNo"]?:?string.Empty;
?84?????????????}
?85?????????????set
?86?????????????{
?87?????????????????ViewState["CreditCardNo"]?=?value;
?88?????????????}
?89?????????}
?90?
?91?????????public?string?CardholderNameText
?92?????????{
?93?????????????get
?94?????????????{
?95?????????????????return?ViewState["CardholderName"]?!=?null???(string)ViewState["CardholderName"]?:?string.Empty;
?96?????????????}
?97?????????????set
?98?????????????{
?99?????????????????ViewState["CardholderName"]?=?value;
100?????????????}
101?????????}
102?
103?????????public?DateTime?ExpirationDateText
104?????????{
105?????????????get
106?????????????{
107?????????????????return?ViewState["ExpirationDate"]?!=?null???(DateTime)ViewState["ExpirationDate"]?:?DateTime.Now;
108?????????????}
109?????????????set
110?????????????{
111?????????????????ViewState["ExpirationDate"]?=?value;
112?????????????}
113?????????}
114?
115?
116?????????#endregion
117?
118?????????#region?events
119?????????private?static?object?ValidateCreditCardFormKey?=?new?object();
120?????????public?event?ValidateCreditCardFormEventHandler?ValidateCreditCardForm
121?????????{
122?????????????add
123?????????????{
124?????????????????Events.AddHandler(ValidateCreditCardFormKey,?value);
125?????????????}
126?????????????remove
127?????????????{
128?????????????????Events.RemoveHandler(ValidateCreditCardFormKey,?value);
129?????????????}
130?????????}
131?
132????????
133?????????protected?void?OnValidateCreditCardForm(ValidateCreditCardFormEventArgs?args)
134?????????{
135?????????????ValidateCreditCardFormEventHandler?handler?=?Events[ValidateCreditCardFormKey]
136?????????????????????????????????????????????????????????????????????????as?ValidateCreditCardFormEventHandler;
137?????????????if?(handler?!=?null)
138?????????????????handler(this,?args);
139?????????}
140?
141?????????#endregion
142?????????void?IPostBackEventHandler.RaisePostBackEvent(string?args)
143?????????{
144?????????????ValidateCreditCardFormEventArgs?ve?=?new?ValidateCreditCardFormEventArgs(
145?????????????????PaymentMethodText,?CreditCardNoText,?CardholderNameText,?ExpirationDateText);
146?
147?????????????OnValidateCreditCardForm(ve);
148?????????}
149?
150?????????private?bool?hasPaymentMethodChanged;
151?????????private?bool?hasCreditCardNoChanged;
152?????????private?bool?hasCardholderNameChanged;
153?????????private?bool?hasExpirationDateChanged;
154?
155?????????bool?IPostBackDataHandler.LoadPostData(string?postDataKey,?NameValueCollection?values)
156?????????{
157?????????????string?paymentMethod?=?values[PaymentMethodListName]?==?"0"???"Master"?:?"Visa";
158?????????????if?(paymentMethod?!=?PaymentMethodText)
159?????????????{
160?????????????????PaymentMethod?=?paymentMethod;
161?????????????????hasPaymentMethodChanged?=?true;
162?????????????}
163?
164?????????????string?creditCardNo?=?values[CreditCardNoTextName];
165?????????????if?(creditCardNo?!=?CreditCardNoText)
166?????????????{
167?????????????????CreditCardNoText?=?creditCardNo;
168?????????????????hasCreditCardNoChanged?=?true;
169?????????????}
170?
171?????????????string?cardholderName?=?values[CardholderNameTextName];
172?????????????if?(cardholderName?!=?CardholderNameText)
173?????????????{
174?????????????????CardholderNameText?=?cardholderName;
175?????????????????hasCardholderNameChanged?=?true;
176?????????????}
177?
178?????????????int?month?=?int.Parse(values[MonthListName]);
179?????????????int?year=int.Parse?(values?[YearListName?]);
180?????????????DateTime?expirationDate=new?DateTime?(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?????????????return?hasExpirationDateChanged||
192?????????????????hasCreditCardNoChanged?||
193?????????????????hasPaymentMethodChanged?||
194?????????????????hasCardholderNameChanged?;
195?
196?????????}
197?
198?????????void?IPostBackDataHandler.RaisePostDataChangedEvent()
199?????????{
200?????????????bool?hasChanged;
201?????????????hasChanged?=?hasCardholderNameChanged?||
202?????????????????hasCreditCardNoChanged?||
203?????????????????hasPaymentMethodChanged?||
204?????????????????hasExpirationDateChanged;
205?
206?????????????if?(hasChanged)
207?????????????{
208?
209?????????????????ValidateCreditCardFormEventArgs?args?=?new?ValidateCreditCardFormEventArgs(
210?????????????????????PaymentMethod,?CreditCardNoText,?CardholderNameText,?ExpirationDateText);
211?
212?????????????????OnValidateCreditCardForm(args);
213?????????????}
214?????????}
215?
216?????}
217?}
218?
總結
以上是生活随笔為你收集整理的ASP.NET自定义控件组件开发 第三章 为控件添加事件 后篇的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JS常用正则匹配
- 下一篇: RHEL5系列之三:GNOME桌面的简单