標籤:ret 傳遞 應用程式 ati namespace div 通過 comm handler
講過了委託,不得不講事件。
事件基於委託,為委託提供了一種發布/訂閱機制。
在發生其他類或對象關注的事情時,類或對象可通過事件通知它們。發送(或引發)事件的類稱為“發行者”,接收(或處理)事件的類稱為“訂戶”。
在典型的 C# Windows 表單或 Web 應用程式中,可訂閱由控制項(如按鈕和列表框)引發的事件。可使用 Visual C# 整合式開發環境 (IDE) 來瀏覽控制項發布的事件,選擇要處理的事件。IDE 會自動添加空事件處理常式方法和訂閱事件的代碼。
事件時對委託的封裝。
事件協助解決委託封裝問題。事件位於委託的頂部,並提供封裝,使得目標源只能聽而不能完全控制的委派物件。
顯示了事件的樣子: -
理解事件:
Button是一個類,當你點擊按鈕的時候,Click事件被觸發。
定時器是一個類,每毫秒tick事件被觸發。
下面通過一個例子來講述一下事件的應用。
定義兩個類CarDealer和Consumer。CarDealer類提供了一個新車到達時觸發的事件,Consumer類訂閱該事件,以獲得新車到達的通知。
事件發行者:CarDealer類提供了EventHandler類型的NewCarInfo事件。事件一般使用帶兩個參數的方法。第一個參數是一個對象,包含事件的寄件者;第二個參數提供了事件的相關資訊。
你可能感到吃驚,沒有定義委託怎麼就定義事件了??其實有了泛型委派EventHandler 委託後,就不再需要委託了。
EventHandler 的文法如下:
public delegate void EventHandler(Object sender,TEventArgs e) where TEventArgs : EventArgs
EventHandler定義了一個處理常式,返回void,接受兩個參數。第一個參數必須是object,第二個參數是T類型,對於T有一個約束,就是它必須派生自基類EventArgs。下面代碼的CarInfoEventArgs就派生自基類EventArgs.
EventArgs是包含事件數目據的類的基類,此類不包含事件數目據,在事件引發時不向事件處理常式傳遞狀態資訊的事件會使用此類。如果事件處理常式需要狀態資訊,則應用程式必須從此類派生一個類來儲存資料。事件處理常式委託的標準簽名定義一個沒有傳回值的方法,其第一個參數的類型為 Object,它引用引發事件的執行個體,第二個參數從 EventArgs 類型派生,它儲存事件數目據。 如果事件不建置事件資料,則第二個參數只是 EventArgs 的一個執行個體。 否則,第二個參數為從 EventArgs 派生的自訂類型,提供儲存事件數目據所需的全部欄位或屬性。
EventHandler 是一種預定義委託,表示事件的事件處理常式方法,它與事件是否建置事件資料無關。 如果事件不建置事件資料,則用 EventArgs 替代泛型型別參數;否則,提供自己的自訂事件數目據類型並用該類型替代泛型型別參數。
使用 EventHandler 的優點在於,如果事件建置事件資料,則無需編寫自己的自訂委託代碼。 此外,.NET Framework 只需一個實現就能支援 EventHandler ,這與替代泛型型別參數的事件數目據類型無關。
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace TestEvent{public class CarInfoEventArgs:EventArgs{public CarInfoEventArgs(string car){this.Car = car;}public string Car{get; private set;}}public class CarDealer{public event EventHandlerNewCarInfo;public void NewCar(string car){Console.WriteLine("CarDealer. new car {0}", car);if (NewCarInfo != null){NewCarInfo(this, new CarInfoEventArgs(car));}}}}
事件監聽器:Consumer類用作事件接聽程式。這個類訂閱了CarDealer類的事件,並定義了NewCarIsHere方法,該方法滿足EventHandler委託的要求,其參數類型是object和CarInfoEventArgs.
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace TestEvent{class Consumer{private string name;public Consumer(string name){this.name = name;}public void NewCarIsHere(object sender, CarInfoEventArgs e){Console.WriteLine("{0}: car {1} is new", name, e.Car);}}}
現在需要串連事件發布器和訂閱器。使用“+=”建立一個訂閱。使用“-=”取消了訂閱。使用代碼:
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace TestEvent{class Program{static void Main(string[] args){var dealer = new CarDealer();var michael = new Consumer("Michael");dealer.NewCarInfo += michael.NewCarIsHere;dealer.NewCar("Mercedes");var nick = new Consumer("Nick");dealer.NewCarInfo += nick.NewCarIsHere;dealer.NewCar("Ferrari");dealer.NewCarInfo -= michael.NewCarIsHere;dealer.NewCar("Toyota");}}}/*-------------------------------------輸出結果:CarDealer. new car MercedesMichael: car Mercedes is newCarDealer. new car FerrariMichael: car Ferrari is newNick: car Ferrari is newCarDealer. new car ToyotaNick: car Toyota is new---------------------------------------*/
淺析C#中的事件