說實話,事件弄得還是很暈,有待於以後的強化吧,下面是我對事件的一點理解
首先,參見大牛的帖子:網上大牛事件講解
下面我來說一說事件的大致流程:
事件委託
事件概述
事件就是當物件或類狀態發生改變時,物件或類發出的資訊或通知。發出資訊的物件或類稱為"事件源",對事件進行處理的方法稱為"接收者",通常事件源在發出狀態改變資訊時,它並不知道由哪個事件接收者來處理.這就需要一種管理機制來協調事件源和接收者,c++中通過函式指標來完成的.在c#中事件使用委託來為觸發時將呼叫的方法提供型別安全的封裝
事件的宣告
1.宣告乙個委託 public delegate void eventhandler(object sender, system.eventargs e);
2.宣告乙個事件 public event eventhandler changed;
3.引發乙個事件 public onchanged(enventargs e) }
4.定義事件處理程式 public mytext_onchanged(object sender,eventargs e)
5.訂閱事件(將事件處理程式新增到事件的呼叫列表中)
mytext.changed += eventhandler(mytext_onchanged);
下面的乙個小例子說明了怎樣定義乙個完整的事件機制:
1using
system;
2using
system.collections.generic;
3using
system.text;45
namespace623
}2425//
對change事件處理的程式
26private
static
void mytext_changed(object
sender, eventargs e)
27\n
",((mytext)sender).text);
29}
30}
3132
public
class
mytext
3348
49//
text屬性
50public
string
text
5153
set5459}
60}61 }
說到底事件就是委託的典型,下面簡單說一下委託:
委託的宣告
public delegate void mydelegate(string str);
注 1、委託的定義和方法的定義類似,只是在前面加了乙個delegate,但委託不是方法,它是一種特殊的型別,看成是一種新的物件型別比較好理解。用於對與該委託有相同簽名的方法呼叫。
2、委託相當於c++中的函式指標,但它是型別安全的。
3、委託是從system.delegate派生,但不能象定義常規型別一樣直接從system.delegate派生,對委託的宣告只能通過上面的宣告格式進行定義。關鍵字delegate通知編譯器這是乙個委託型別,從而在編譯的時候對該類進行封裝,對這一過程c#定義了專門的語法來處理這一過程。
4、不能從乙個委託型別進行派生,因為它也是預設sealed的。
5、委託即可以對靜態方法進行呼叫也可以對例項方法進行呼叫。
6、每個委託型別包含乙個自己的呼叫列表,當組合乙個委託或從乙個委託中刪除乙個委託時都將產生個新的呼叫列表。
7、兩個不同型別的委託即使它們有相同的簽名和返回值,但還是兩個不同型別的委託。但其實在使用中可看作是相同的。
委託的比較
c#中對委託定義了兩個操作符 == 和 != 在以下情況下兩個委託是相等的:
1、當兩個委託都同時為null的時候;
2、當兩個委託都不為null時,下列情況下是相等的。
a、當兩個委託的各自的呼叫列表只含有乙個入口點的時候,在下列情況下是相等的:
(1) 呼叫同一物件的同一靜態方法
(2) 呼叫同一物件的同一例項方法
b、當兩個委託具有多個入口點時, 在下列情況下是相等的:
(1)只有當它們呼叫列表中的呼叫的方法按順序都一一對應相同的物件及物件的同一方法的時候,如上所述的兩個不同型別的委託但是它們具有相同的簽名和返回值時,只要滿足上述條件的,即使它們型別不同,但比較的結果也是相同的。
委託的異常處理
當呼叫該委託的方法中發生了異常時,首先在呼叫該委託的方法中搜尋catch語句塊。如果沒有,則去該委託呼叫的方法中去尋找有沒有catch語句塊,這和呼叫方法發生異常的處理是一樣的。
當呼叫乙個為null的委託即委託中列表中不存在呼叫方法時,將發生nullrefrenceexception
委託的注意點: 當乙個委託有多個入口點的時候,呼叫委託將依該委託的呼叫列表中的方法的順序依次呼叫.這些方法共享乙個引數集合,所以當委託有返回值的時候呼叫完這個委託後的返回值是最後乙個方法的返回值或是有out引數.如果該委託的引數為ref(引用型別),那麼在招待第乙個方法的時候如果對這個引數的值有所改變,那麼這個改變將會影響到後面的方法呼叫。
委託的乙個例子:
1using
system;
2using
system.collections.generic;
3using
system.text;45
namespace647
}4849//
宣告乙個委託mydelegate
50public
delegate
void mydelegate(string
str);
5152
public
classc53
", str);57}
5859
public
static
void m2(string
str)60"
, str);62}
6364
public
void m3(string
str)65"
, str);67}
68}6970
public
class
c171
", str);75}
76}7778
public
class
c279
", str);83}
84}
85 }
下面貼上我自己寫的鍵盤註冊事件:
1using
system;
2using
system.collections.generic;
3using
system.text;
4using
system.threading;56
namespace
假期小練2717
}1819public
class
keydown:eventargs
20
26set 27}
28public keydown(string ss):base
()2932}
3334
class
keydown
3545}46
47class
jieshou
4853
public
void chulii(object
sender,keydown e)
54 57}
58 }
理解C 事件
如果做過gui程式開發,可能對上面的描述會比較熟悉。在gui程式中,單擊乙個button會觸發乙個click事件,然後會執行一系列的操作,這一系列的操作就被存放在乙個委託例項中。接下來我們就看看事件。使用委託中的問題 回到前面文章中蘋果和富士康的例子,蘋果將iphone的組裝 包裝和運輸的工作全部委...
理解C 事件
前面文章中介紹了委託相關的概念,委託例項儲存這乙個或一組操作,程式中將在某個特定的時刻通過委託例項使用這些操作。如果做過gui程式開發,可能對上面的描述會比較熟悉。在gui程式中,單擊乙個button會觸發乙個click事件,然後會執行一系列的操作,這一系列的操作就被存放在乙個委託例項中。接下來我們...
對C 事件的理解
很長一段時間我都覺得事件是個很神奇的東西,今天專門看了下書,發現原來一切都已經被c 封裝好了,如我的winform控制項的單擊事件 click 雙擊事件 doubleclick 事件是怎麼實現的細節,被封裝在了eventhandler類裡面.我們在用的時候真接用eventhandler委託定義事件就...