目錄:
介紹委托和事件
聲明事件(定義事件)
注冊事件
實現事件
觸發事件
為事件增加“添加/刪除”方法
一 介紹委托和事件
事件是特殊化的委托,委托是事件的基礎,所以在介紹事件之前先介紹一下委托。
委托:使用委托可以將方法應用(不是方法)封裝在委托對象內,然后將委托對象傳遞給調用方法的代碼,這樣編譯的時候代碼就沒有必要知道調用哪個方法。通過使用委托程序能夠在運行時動態的調用不供的方法。
事件:事件是對象發送的消息,發送信號通知客戶發生了操作。這個操作可能是由鼠標單擊引起的,也可能是由某些其他的程序邏輯觸發的。事件的發送方不需要知道那個對象或者方法接收它引發的事件,發送方只需知道在它和接收方之間存在的中介(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--;
}
}
|