C# 事件 【博主】反骨仔 【原文】http://www.cnblogs.com/liqingwen/p/6057301.html 序 之前通過《C# 知識回顧 - 委托 delegate》、《C# 知識回顧 - 委托 delegate (續)》介紹了委托的基本知識,這次我們來看看事件。 目錄 C# ...
C# 事件
【博主】反骨仔 【原文】http://www.cnblogs.com/liqingwen/p/6057301.html
序
之前通過《C# 知識回顧 - 委托 delegate》、《C# 知識回顧 - 委托 delegate (續)》介紹了委托的基本知識,這次我們來看看事件。
目錄
- What's 事件
- 事件的屬性彙總
- 事件的訂閱和取消
- 使用 Visual Studio IDE 訂閱事件
- 以編程方式訂閱事件
- 使用匿名方法訂閱事件
- 取消訂閱
一、What's 事件
類或對象可以通過事件向其他類或對象通知發生的相關事情。發送(或引發)事件的類稱為“發行者”,接收(或處理)事件的類稱為“訂戶”(訂閱者)。
在典型的 C# Windows 窗體或 Web 應用程式中,可訂閱由按鈕和列表框等控制項引發的事件。 可以使用 Visual C# 集成的開發環境 (IDE) 來瀏覽控制項發佈的事件,並選擇想要處理的事件。 IDE 將自動添加空白事件處理程式方法和訂閱該事件的代碼。
二、事件的屬性彙總
-
發行者確定何時引發事件;訂戶確定對事件作出何種響應。
-
一個事件可以有多個訂戶。 訂戶可以處理來自多個發行者的多個事件。
-
沒有訂戶的事件永遠也不會引發。
-
事件通常用於表示用戶操作,例如單擊按鈕或圖形用戶界面中的菜單選項。
-
當事件具有多個訂戶時,引發該事件時會同步調用事件處理程式。 若要非同步調用事件
-
事件基於 EventHandler 委托和 EventArgs 基類。
三、事件的訂閱和取消
如果您想編寫引發事件時調用的自定義代碼,則可以訂閱由其他類發佈的事件。 例如,可以訂閱某個按鈕的 click 事件,以使應用程式在用戶單擊該按鈕時執行一些有用的操作。
1.使用 Visual Studio IDE 訂閱事件
圖3-1-1 新建一個 WinForm 項目
圖3-1-2 由圖1雙擊時所自動創建的代碼
圖3-1-3 除了圖2,在 InitializeComponent 方法也自動增加了這行代碼
2.以編程方式訂閱事件
假設現在是一個新的 WinForm 程式,我們通過手動的方式自己創建事件。在 InitializeComponent 方法下麵輸入 this.Load +=,然後會出現提示,這時我們按下“Tab 鍵”,
圖3-2-1
會發現也會自動創建事件處理程式,效果跟上一節的直接雙擊空白處創建的代碼可以說是一致的,代碼如下:
1 public partial class Form1 : Form 2 { 3 public Form1() 4 { 5 InitializeComponent(); 6 7 this.Load += Form1_Load; 8 } 9 10 private void Form1_Load(object sender, EventArgs e) 11 { 12 throw new NotImplementedException(); 13 } 14 }
這次,我們直接採用 lambda 方式完成事件的註冊:點擊空白處顯示滑鼠點擊時的坐標。
1 public partial class Form1 : Form 2 { 3 public Form1() 4 { 5 InitializeComponent(); 6 7 //this.Load += Form1_Load; 8 9 //點擊事件(lambda 方式創建) 10 this.Click += (s, e) => 11 { 12 MessageBox.Show($"{((MouseEventArgs)e).Location}"); 13 }; 14 } 15 16 private void Form1_Load(object sender, EventArgs e) 17 { 18 throw new NotImplementedException(); 19 } 20 }
圖3-2-2
3.使用匿名方法訂閱事件
1 public Form1() 2 { 3 InitializeComponent(); 4 5 //this.Load += Form1_Load; 6 7 //點擊事件(lambda 方式創建) 8 //this.Click += (s, e) => 9 //{ 10 // MessageBox.Show($"{((MouseEventArgs)e).Location}"); 11 //}; 12 13 //使用匿名方法創建事件 14 this.Click += delegate (object sender, EventArgs e) 15 { 16 var mouseEventArgs = (MouseEventArgs)e; 17 var mouseLocation = mouseEventArgs.Location; 18 19 MessageBox.Show($"X: {mouseLocation.X}, Y: {mouseLocation.Y}"); 20 }; 21 }
【註意】如果使用匿名函數訂閱事件,事件的取消訂閱過程將比較麻煩。這種情況下若要取消訂閱,必須返回到該事件的訂閱代碼,將該匿名方法存儲在委托變數中,然後將此委托添加到該事件中。一般來說,如果必須在後面的代碼中取消訂閱某個事件,則建議您不要使用匿名函數訂閱此事件。
4.取消訂閱
要防止在引發事件時調用事件處理程式,請取消訂閱該事件。要防止資源泄露,應在釋放訂戶對象之前取消訂閱事件。在取消訂閱事件之前,在發佈對象中作為該事件的基礎的多路廣播委托會引用封裝了訂戶的事件處理程式的委托。只要發佈對象保持該引用,垃圾回收功能就不會刪除訂戶對象。使用減法賦值運算符 (-=) 取消訂閱事件。
this.Load -= Form1_Load; //使用減法賦值運算符 (-=) 取消訂閱事件
【備註】所有訂戶都取消訂閱事件後,發行者類中的事件實例將設置為 null。
傳送門
《C# 知識回顧 - 表達式樹 Expression Trees》
《C# 知識回顧 - 特性 Attribute》、《剖析 AssemblyInfo.cs - 瞭解常用的特性 Attribute》《C# 知識回顧 - 委托 delegate》、《C# 知識回顧 - 委托 delegate (續)》
--預覽版整理中--
【參考】微軟官方文檔