1.定義事件時最好依循以下慣例:
1.不要有回傳值
2.在參數列提供來源物件
3.使用EventArgs來包裝參數
1.不要有回傳值之原因:
一個事件可能有多個訂閱者,如果每個訂閱者都回傳值,經過一輪呼叫多個事件處理常式(訂閱者自型定義處理事件之方法),
發行者不會知道要採用哪個回傳值。
基於以上原因:事件處理常式也不會有回傳值且宣告委派型別也是如此。
public delegate void TextChangedEventHandler(string oldValue,string newValue);
2.在參數列提供來源物件
事件與事件處理常式之間的關係是多對多的,這表示一個事件可以提供多個訂閱者訂閱。
而多個事件也可以指向同一個事件處理常式。
假設我扪要十個按鈕按下後通通都做同一個事件處理常式:
button01.Clisk += this.SharedButtonClickHandler;
button02.Clisk += this.SharedButtonClickHandler;
...
這時候共用的事件處理常式:SharedButtonClickHandler,會需要知道是由哪個物件來觸發的,以便做出回應,
故需要傳入來源物件也就是這個原因。
在慣例上宣告委派型別時,第一個參數會是觸發事件之來源物件(型別:object,參數:sender)。
delegate void TextChangedHandler(object sender, strign olaValue, string newValue);
3.使用EventArgs來包裝參數
事件參數型別與參數個數會影響發行者類別與訂閱者類別之間的關係。
怎說? 一但發行者改變了事件之參數的個數或型別,相對的訂閱者的參數各數或型別也要改成相同,否則不能互相呼應。
因此.NET提供了一個通用事件參數類別:EventArgs。
使您可以直接使用EventArgs類別或繼承EventArgs來延伸它傳遞事件參數。
如此事件參數永遠都是兩個(object sender, EvaentArgs args); 第一個是來源物件,第二個是事件用到參數(不論是0個或多個都會包在args內)。
EventArgs類別之實做如下:
可以看到此類別提供一個靜態成員且唯獨成員:Empty,所以如果事件不需要任何參數可以直接傳入Empty.Empty。(靜態成員可以直接用不用建立類別實例)
不過這樣.NET內件類別並不符合我扪的需要,因為我扪需要傳參數,這時候就需要從EventArgs衍生新的類別來使用。
有了此參數類別後,我扪委派別可以改成如此:
delegate void TextChangedEventHandler(object sender, TextChangedEventArgs args);
結論:
當事件參數很多時,可以採用此做法,因為就算參數在多,參數列永遠都是兩個參數sender and args。
完整範例:
https://drive.google.com/open?id=0B7xmgb1
TKMCTRTltcHdnckVLTW8&authuser=0
留言列表