1.事件的含义
事件和异常类似,它们都是由对象引发,我们可以提供代码处理它们。不同的是事件并没有使用try ..catch这样的代码来处理,而是要订阅事件,订阅的含义是提供一段事件处理代码,在事件发送时执行这段代码,这段代码也称为事件处理程序。
单个事件可以提供多个事件处理程序,每个事件处理程序都会执行。
事件的本质是一个event修饰的委托。
2.实现自定义事件的步骤
1)创建委托;
2)定义事件;
3)编写事件处理程序;
4)订阅事件。
比如我们有一个即时消息的应用程序,Connection表示用户建立的一个远程连接,当远程连接收到客户的信息时即刻显示出来。
public class MessageArrivedEvnetArgs:EventArgs { private string message; public string Message { get { return message; } } public MessageArrivedEvnetArgs() { message = "No Message Sent."; } public MessageArrivedEvnetArgs(string message) { this.message = message; } } public delegate void MessageHandler(Connection sender,MessageArrivedEvnetArgs e);//1.定义委托 public class Connection { public event MessageHandler MessageArrived;//2.定义事件 public string name; private Timer pollTimer; private Random random = new Random(); public Connection(string name) { this.name = name; pollTimer = new Timer(); pollTimer.Elapsed +=new ElapsedEventHandler(CheckForMessage);//订阅事件 } public void Connect() { pollTimer.Start(); } public void DisConnected() { pollTimer.Stop(); } public void CheckForMessage(object sender, ElapsedEventArgs e) { if (random.Next(9) == 0 && this.MessageArrived != null)//触发事件 { MessageArrived(this,new MessageArrivedEvnetArgs("Hollo Mum!")); } } } class Display { public void DisplayMessage(Connection sender, MessageArrivedEvnetArgs e)//3.编写时间处理程序 { Console.WriteLine("Form:" + sender.name ); Console.WriteLine("Message :"+ e.Message); } } class Program { static void Main(string[] args) { Connection con = new Connection("Conn1"); Display displayer = new Display(); con.MessageArrived += new MessageHandler(displayer.DisplayMessage); Connection con2 = new Connection("Conn2"); con2.MessageArrived += new MessageHandler(displayer.DisplayMessage);//4.订阅事件 con2.Connect(); Console.ReadLine(); } }
3.事件参数的含义
一般的事件都有两个参数,比如 Timer.Elapsed事件中
object sender是指引发事件的对象本身
ElapsedEventArgs e是事件传递的信息
public void CheckForMessage(object sender, ElapsedEventArgs e) { if (random.Next(9) == 0 && this.MessageArrived != null)//触发事件 { MessageArrived(this,new MessageArrivedEvnetArgs("Hollo Mum!")); } }
在通用的事件处理程序中,一个事件处理程序可能关联了几个对象产生的事件,可以通过sender判断引发事件的对象是什么,进而做针对性的操作。
一般的事件,比如Click事件都使用EventArgs对象传递信息,实际上它并没有传递什么信息,如果需要传递自己的信息,可以继承EventArgs并添加自己的属性,比如ElapsedEventArgs
// 摘要: // 为 System.Timers.Timer.Elapsed 事件提供数据。 public class ElapsedEventArgs : EventArgs { // 摘要: // 获取引发 System.Timers.Timer.Elapsed 事件的时间。 // // 返回结果: // 引发 System.Timers.Timer.Elapsed 事件的时间。 public DateTime SignalTime { get; } }
4.EventHandler<T>
EventHandler<T>强类型化时间第二个参数为T类型,他的定义如下
public delegate void EventHandler<TEventArgs>(object sender, TEventArgs e);
使用EventHandler<T>可以以另一个种方式定义事件
public class MessageArrivedEvnetArgs:EventArgs { private string message; public string Message { get { return message; } } public MessageArrivedEvnetArgs() { message = "No Message Sent."; } public MessageArrivedEvnetArgs(string message) { this.message = message; } } public class Connection { //public event MessageHandler MessageArrived;//2.定义事件 public event EventHandler<MessageArrivedEvnetArgs> MessageArrived;//2.定义事件 public string name; private Timer pollTimer; private Random random = new Random(); public Connection(string name) { this.name = name; pollTimer = new Timer(); pollTimer.Elapsed +=new ElapsedEventHandler(CheckForMessage);//订阅事件 } public void Connect() { pollTimer.Start(); } public void DisConnected() { pollTimer.Stop(); } public void CheckForMessage(object sender, ElapsedEventArgs e) { if (random.Next(9) == 0 && this.MessageArrived != null)//触发事件 { MessageArrived(this,new MessageArrivedEvnetArgs("Hollo Mum!")); } } } class Display { public void DisplayMessage(Connection sender, MessageArrivedEvnetArgs e)//3.编写时间处理程序 { Console.WriteLine("Form:" + sender.name ); Console.WriteLine("Message :"+ e.Message); } public void DisplayMessage2(object sender, MessageArrivedEvnetArgs e)//3.编写时间处理程序 { Console.WriteLine("Form2:" + ((Connection)sender).name); Console.WriteLine("Message2 :" + e.Message); } } class Program { static void Main(string[] args) { Connection con = new Connection("con1"); Display d = new Display(); con.MessageArrived += new EventHandler<MessageArrivedEvnetArgs>(d.DisplayMessage2); con.Connect(); Console.ReadLine(); } }