.Net Framework中的標准委托,已經定義在命名空間System中,
namespace System
{
public delegate void EventHandler(object sender, EventArgs e);
}
.Net Framwork類庫中的所有事件均基於EventHandler委托。
其中EventArgs參數是可以自定義,必須繼承EventArgs類:
public class CustomEventArgs:EventArgs
發布事件有三種方式:
1. 使用.net framework標准委托
public event EventHandler RaiseCustomEvent;
2. 自定義EventArgs參數
public event CustomEventHandler RaiseCustomEvent;
3. 自定義EventArgs參數,泛型的表達方式
public event EventHandler<CustomEventArgs> RaiseCustomEvent;
如何:發布符合.net framework准則的事件
首先分兩個類:
1. 發行者類(Publisher),發送Sends(引發Raise)事件的類,這個類做兩件事
窗體(Form)和控件(control)的類中都發布了事件(Load,Click等),事件的觸發程序同樣能找到,如下:
protected virtual void OnClick(EventArgs e);
2. 訂閱者類(Subscriber),接收Receive(處理Handle)事件的類,這個類做兩件事
當你雙擊Form1中的一個按鈕Button1,會直接進入
private void button1_Click(object sender, EventArgs e)
{
}
其實就是在寫事件的處理程序;在Form1.Designer.cs中會自動注冊按鈕雙擊事件
this.button1.Click += new System.EventHandler(this.button1_Click);
下面來看一個例子,是一個比較標准的方式添加自定義的事件:
namespace DotNetEvents
{
class Program
{
static void Main(string[] args)
{
Publisher pub = new Publisher();
Subscriber sub1 = new Subscriber("sub1", pub);
Subscriber sub2 = new Subscriber("sub2", pub);
//Call the method that raises the event
pub.DoSomething();
Console.WriteLine("Press Enter to close this window.");
Console.ReadKey();
}
}
//Define a class to hold custom event info
public class CustomEventArgs:EventArgs
{
private string message;
public CustomEventArgs (string s)
{
message = s;
}
public string Message
{
get { return message;}
set { message = value; }
}
}
//Class that publishes an event
class Publisher
{
//Declare the event using EventHandler<T>
public event EventHandler<CustomEventArgs> RaiseCustomEvent;
public void DoSomething()
{
//Write some code that does something useful here
//then raise the event.You can also raise an event
//before you execute a block of code.
OnRaiseCustomEvent(new CustomEventArgs("Did something"));
}
//Wrap event invocations inside a protected virtual method
//to allow derived classes to oveeride the event invocation behavior
protected virtual void OnRaiseCustomEvent(CustomEventArgs e)
{
//Make a temporary copy of the event to avoid possibility of
//a race condition if the last subscriber unsubscribes
//immediately after the null check and before the event is raise
if(RaiseCustomEvent !=null )
{
e.Message = String.Format(" at {0}", DateTime.Now.ToString());
RaiseCustomEvent(this, e);
}
}
}
//Class that subscribes to an event
class Subscriber
{
private string id;
public Subscriber (string ID,Publisher pub)
{
id = ID;
//Subscribe to the event suing C# 2.0 syntax
pub.RaiseCustomEvent += HandleCustomEvent;
}
//Define what action to take when the event is raised
void HandleCustomEvent(object sender,CustomEventArgs e)
{
Console.WriteLine(id + " receive this message: {0}", e.Message);
}
}
}