一 介紹委託和事件
事件是特殊化的委託,委託是事件的基礎,所以在介紹事件之前先介紹一下委託。
委託:使用委託可以將方法應用(不是方法)封裝在委派物件內,然後將委派物件傳遞給調用方法的代碼,這樣編譯的時候代碼就沒有必要知道調用哪個方法。通過使用委託程式能夠在運行時動態調用不供的方法。
事件:事件是對象發送的訊息,發送訊號通知客戶發生了操作。這個操作可能是由按一下滑鼠引起的,也可能是由某些其他的程式邏輯觸發的。事件的發送方不需要知道那個對象或者方法接收它引發的事件,發送方只需知道在它和接收方之間存在的中介(Deletgate)
二. 聲明事件(定義事件)
在GUI圖形介面中的事件(單擊按鈕或者選擇菜單等)是已經定義好的事件,所需要的就是註冊事件。我們也可以自己定義聲明事件,可以將自己定義的事件應用到程式的任何地方。事件和委託是分不開的,c# 中使用委託來聲明事件。
如果在類裡面聲明事件,那麼必須先聲明該事件的委託類型,也可以使用一個事先已經聲明好的委託類型。
下面是一個聲明事件的例子:
using system;
public delegate void MenuHandler()//事先申明一個委託,也可以在類的內部聲明委託類型
public class Menuitem //聲明一個功能表項目的類
{
public event MenuHadler MenuSelection;// 聲明一個事件並指定它的委託類型
string text ;//聲明一個字串
public MenuItem(string text) //功能表項目類的建構函式
{
this.text=text; // 初始化text字串
}
public void Fird()
{
MenuSelection; //定義一個觸發事件的方法(後面將用到)
}
public string Text //定義屬性
{
get
{
return text;
}
set
{
text=value;
}
}
}
程式首先定義個一個叫做MenuHandler的委託,然後定義了叫做 MenuItem 的類,MenuItem類包含了一個MenuSelection 事件(菜單被選擇事件),事件的委託類型是MenuHandler。事件的聲明完成啦,下面開始註冊事件
三.註冊事件
這裡先講一下 publisher/subscriber(發行者/訂閱者)模式,因為事件就是從這個模式繼承下來的。一個訊息的傳送者 (Sender) 稱之為 Publisher,而該訊息的接收者 (Receiver),則稱之為Subscriber,Subscriber(訂閱者)在Publisher(發行者)處註冊自己,Publisher發生改變的時候,通知Subscriber做適當的操作,很類似設計模式中的Observer 。
在這裡我們認為註冊的程式就是訂閱者(Subscriber)。事件相當於發行者(Publisher),下面的程式表明了如何把訂閱器串連到發布器:
using system;
public class DelegateAndEvents //定義個註冊事件的類
{
public static void int Main ()
{
SiteManager sm=new SiteManager (); // SiteManager是一個網站管理類
MenuItem AddMenu= new MenuItem(“Add”) //定義一個新的事件類別
MenuItem DelMenu=new MenuItem(“Delete”) //定義另外一個新的事件類別
//通過委託,sm類的Addsite 方法 註冊到事件中
AddMenu.MenuSelelction+=new MenuHandler(sm.AddSite)
//通過委託,sm類的DeleteSite 方法 註冊到事件中
DelMenu.MenuSelelction+=new MenuHandler(sm. DeleteSite)
}
}
從註冊事件的那行代碼來看,事件就像是事件類別的一個欄位(屬性),但是對它的訪問是很受限制的,只能通過:在該欄位上撰寫新的委託(+=)或者從欄位(可能是複合欄位)移除委託(-=)進行訪問,
移除註冊事件:DelMenu.MenuSelelction-=new MenuHandler(sm. DeleteSite)
四.實現事件
這裡就要講到上個例子中的SiteManager類,它包含了事件需要實現的方法(AddSite,DeleteSite),SiteManager類的方法一定要符合事件的委託類型和傳回型別,在委託添加到事件前,該方法能夠以這個方式付給委託。
using system;
public class SiteManger //網站管理類
{
public SiteManger() //建構函式 初始設定變數
{
//impelement something
}
public void AddSite() //方法要符合委託的類型
{
// impelement 執行添加網站的作業碼
}
public void DeleteSite() //方法要符合委託的類型
{
// impelement 執行刪除網站的作業碼
}
}
SiteManger類的方法要符合委託類型,這樣他的方法可以很方便的當作事件的方法使用。
五. 觸發事件
當呼叫事件時就可以說時觸發了事件。事件是從定義它的類中觸發的
樣本
using system;
public class menu //定義一個菜單類
{
public menu(strng title) //類的建構函式
{
//初始設定變數
}
public void Run() //觸發事件的過程
{
//聲明一個功能表項目對象(menuItem前面已經定義)
menuItem myMenuItem=new menuItem }
myMenuItem.fire //調用fire 方法觸發事件,事件執行SiteManger類的方法
}
到此為止我就完成了整個事件的實現過程。
六.為事件增加“添加/刪除”方法
如果由大量的方法需要註冊到事件時,可以為為事件增加 Add,Remove 方法。通過訪問事件的“添加/刪除方法”來註冊方法
樣本:
using sytem;
pulic Delete ovid MenuHandler(object sender,EventArgs e); //樣本1的變形
public class MenuItem
{
int numberof Events;
string tex;
private MenuHandler mh=null; //內部得一個委託
public event MenuHandler MenuSelecton
{
add //增加“添加”方法
{
mh+=value;
nuberofevents++;
}
remove
{
mh-=value;
numberofevents--;
}
}