事件(event)是.net中允许我们定义的一种成员,事件是建立在委托(delegate)的基础上,.net的事件模型为我们提供了定义事件的这种能力,方便我们在程序设计时来使用事件来完成一些我们想要做的事情,Asp.Net框架中的WebForm模型就是基于事件驱动模型的一种框架,它模拟了一套winForm的编程模型。这种事件驱动在我们平时的程序设计中随处可见,一个button按钮被单击,就会触发一次单击事件,可以说我们在编程的时候时时刻刻都在和事件打交道,那么我们怎么来定义自己的事件呢?下面我们通过一个场景来引出使用场景,以及通过代码演示来实现自定义事件,最后在对事件的定义进行一个总结。

  • 需求: 

      我们平时工作中每天都会受到一些邮件,难免我们会忘记查收,有时就会错过一些及时要处理的重要邮件,那么希望在邮件到达的时候有个短信/QQ/MSN的即使通知,这样我们就可以通过提醒及时的查看邮件了。

  • 分析:

      1.每次邮件到达的时候我们就要触发一个事件,这个事件中发出通知提示信息;

      2.必须要有订阅这个事件的对象;

      3.消息传递的参数;

  • 实现:

      定义消息的参数,也就是时间传递的参数,在C#中的命名约定中事件参数是也EventArgs结尾的,如:MsgEventArgs,并且参数要继承自EventArgs基类,那么,将邮件中的一些数据封装成MailMsgEventArgs事件参数如下:

自定义事件_事件驱动自定义事件_事件触发_02Code
    public class MailMsgEventArgs:EventArgs
    {
        
private string _from = String.Empty;
        
private string _to = String.Empty;
        
private string _subject = String.Empty;
        
private string _body = String.Empty;

        
public string From
        { 
            
get { return _from; }
            
set { _from = value; }        
        }
        
public string To
        {
            
get { return _to; }
            
set { _to = value; }
        }
        
public string Subject
        {
            
get { return _subject; }
            
set { _subject = value; }
        }
        
public string Body
        {
            
get { return _body; }
            
set { _body = value; }
        }
        
public MailMsgEventArgs(string from, string to, string subject, string body)
        {
            
this._from = from;
            
this._to = to;
            
this._subject = subject;
            
this._body = body;
        }
    }

 接着定义一个委托类型的回调方法原型,参数类型为上面定义的MailMsgEventArgs:

public delegate void MailMsgEventHandler(Object sender, MailMsgEventArgs e);

然后定义事件成员:

       //定义事件成员
        public event MailMsgEventHandler MailMsg = null;

 下面定义一个受保护虚方法来负责通知事件的订阅对象:

 

自定义事件_事件驱动自定义事件_事件触发_02Code
        protected virtual void OnMailMsg(MailMsgEventArgs e)
        {
            
if (MailMsg != null)//判断是否有对象订阅了该事件,如果有订阅就调用MailMsg(this, e)发布通知
            {
                MailMsg(
this, e);
            }
        }

  下面是定义事件触发的一个方法,在邮件到达的时调用该方法: 

自定义事件_事件驱动自定义事件_事件触发_02Code
        public void SimulateArrivingMsg(string from,string to,string subject,string body)
        {
            MailMsgEventArgs e
=new MailMsgEventArgs (from,to,subject,body);
            OnMailMsg(e);
        }

 接下来就要定义QQ/短信/MSN来侦听订阅上述定义的事件,在邮件到来的时候收到消息:

先定义一个公共的侦听基类MailListening来处理消息发送的内容:

自定义事件_事件驱动自定义事件_事件触发_02Code
    public class MailListening
    {
        
protected void SendMsg(MailMsgEventArgs e)
        {
            Console.WriteLine(
"你的邮箱{0},从{1}收到了一封标题为:{2}的信邮件", e.To, e.From, e.Subject);
            Console.WriteLine(
"邮件内容为:{0}", e.Body);
        }
    }

  QQ侦听类,在构造方法中对上面定义的时间进行订阅,并在订阅的方法中发功消息通知:

自定义事件_事件驱动自定义事件_事件触发_02Code
    public class QQListening:MailListening
    {
        
public QQListening(MailManager mailManager)
        {
            mailManager.MailMsg 
+= new MailManager.MailMsgEventHandler(mailManager_MailMsg);
        }

        
void mailManager_MailMsg(object sender, MailMsgEventArgs e)
        {
            Console.WriteLine(
"QQ消息:");
            SendMsg(e);
        }       
    }

 短信息侦听类,在构造方法中对上面定义的时间进行订阅,并在订阅的方法中发功消息通知: 

 

自定义事件_事件驱动自定义事件_事件触发_02Code
    public class SMSListening:MailListening
    {
        
public SMSListening(MailManager mailManager)
        {
            mailManager.MailMsg 
+= new MailManager.MailMsgEventHandler(mailManager_MailMsg);
        }

        
void mailManager_MailMsg(object sender, MailMsgEventArgs e)
        {
            Console.WriteLine(
"短消息:");
            SendMsg(e);
        }
    }

 

户端调用: 

自定义事件_事件驱动自定义事件_事件触发_02Code
            EventSample.MailManager mailManager = new RedStar.ConApp.EventSample.MailManager();           
            EventSample.QQListening qqListening 
= new RedStar.ConApp.EventSample.QQListening(mailManager);
            EventSample.SMSListening smsListening 
= new RedStar.ConApp.EventSample.SMSListening(mailManager);
            
//收到邮件进行对订阅的工具进行通知
            mailManager.SimulateArrivingMsg("蓝之风""15912345678@139.com""邮件通知""通知内容自定义事件_事件驱动_15");
            Console.WriteLine(
"按任意键继续自定义事件_事件驱动_15");
            Console.ReadLine();

 输出结果如下:

 

总结:

定义一个事件需要如下几个步骤:

1.定义一个类型用于保存需要传给时间通知的的信息,事件参数(EventArgs)

2.定义一个委托类型,用于指定事件触发时被调用的方法原型(EventHandler)

3.定义一个事件成员

4.定义一个受保护的虚方法,负责通知时间的订阅对象

5.定义一个方法,将输入转化正期望的事件

事件调用:

1.定义事件的侦听对象,来订阅事件

2.触发事件