C#事件学习

来源:互联网 发布:java反射获取私有属性 编辑:程序博客网 时间:2024/06/05 10:11


在C#语言中,事件机制有以下特征:

1. 事件和变量、方法、属性一样,也是类的一种成员。

使用事件机制可以实现:当类对象的某个状态发生变化(事件被触发)时,系统将会通过某种“途径”调用类中的有关处理这个事件的方法.

2. 在.NET框架中,事件是将事件发送者(触发事件的对象)与事件接收者(处理事件的方法)相关联的一种代理类,即事件机制是通过

代理来实现的。当一个事件被触发时,由该事件的代理来通知(调用)处理该事件的相应方法.

3. 事件也支持多播(多重代理)。一个事件发送者(触发事件的对象)可以同时触发多个处理事件的方法。


在C#中事件机制的工作过程如下:

(1) 将实际应用中需通过事件机制解决的问题对象注册到相应的事件处理程序上,表示今后当该对象的状态变化时,该对象有权使用它注册的事件处理程序。

(2) 当事件发生时,触发事件的对象代理就会调用该对象所有已注册的事件处理程序。


为了实现上述的“事件机制”,C#语言创建和使用事件的语言结构描述包括以下步骤:

1.为事件定义一个代理

用使用事件,首先必须为它创建一个代理。为事件定义一个代理的语句格式如下:

delegate void 代理名([触发事件的对象名,事件参数]);

在.NET框架的System命名空间内,已有一个专门用于处理事件的代理类EventHandler,它可用于处理各种事件,其原型代码如下:

public delegate void EventHandler(Object sender,EventArgs e);


2.创建一个包含事件信息的类

事件信息将作为事件参数发送给事件接收者

在.NET框架的System命名空间内,已为用户提供了一个事件参数EventArgs。这个类是.NET框架中所有事件参数的基类,用于存储所需的数据成员(其中定义的数据是将传递给事件处理方法的数据)。


3.创建包含事件成员的类(又称为事件类)

(1) 定义事件成员

event 事件的代理名 事件名

(2) 创建触发事件的方法或属性等成员

触发事件的方法或属性等成员用于接收触发事件的触发信息,并通过事件对象调用事件代理,并进而实现调用事件处理方法.


4.创建事件处理方法

当事件被触发后,将通过该事件的代理来调用处理该事件的事件处理方法。处理事件的方法是用事件代理的格式创建的,其格式如下:

void 事件处理方法名(Object sender,xxxEventArgs argName)

{

//事件处理方法代码
}


5.将事件处理方法和事件关联起来

(1)创建事件类的对象

(2)将事件处理方法与事件对象关联

事件类对象名.事件类中定义的事件成员+=new 事件代理名(事件处理方法名列表);


以下我们来看一个E-mail的事件的例子:

一个E-mail事件的处理程序。当收到一个E-mail消息时,程序就把这条消息转发给传真机或直接显示在屏幕上。事件处理方法

using System;
namespace EventTest
{
    //包含事件成员的事件类MailManager
   class MailManager
   {
       //1.定义事件代理类
       public delegate void MailMagEventHandler(Object sender,MailMagEventArgs args);
       //2.定义事件参数类
       public class MailMagEventArgs : EventArgs
       {
           public MailMagEventArgs(string from,string to,string subject,string body)
           {
               this.from = from;
               this.to = to;
               this.subject = subject;
               this.body = body;
           }
           public readonly string from, to, subject, body;
       }
       //3.定义事件成员
       public event MailMagEventHandler MailMag;
       //4.定义触发事件的方法
       protected virtual void OnMailMag(MailMagEventArgs e)
       {
           //判读事件成员MailMag上是否绑定了事件处理方法
           if (MailMag != null)
           {
               //如绑定了事件处理方法,则调用这些方法
               MailMag(this, e);
           }
             
       }
       //5.接收触发事件的信息的方法
       public void SimulateArrivingMag(string from,string to,string subject,string body)
       {
           //首先创建事件参数实例
           MailMagEventArgs e = new MailMagEventArgs(from, to, subject, body);
           //调用触发事件的方法
           OnMailMag(e);
       }
   }
    //包含事件处理方法的类
    class Fax
    {
        public string FaxId;
        public Fax(MailManager mm)
        {
            //首先为事件管理器MailManager创建一个MailMagEventHandler事件代理对象
            //并把代理的事件处理方法FaxMag注册到MailManager的MailMag事件成员上
            mm.MailMag += new MailManager.MailMagEventHandler(FaxMag);
        }
       
        /// <summary>
        /// 事件处理方法
        /// </summary>
        /// <param name="sender">触发事件的对象,即MailManager对象</param>
        /// <param name="e">事件参数,包含与事件有关的信息,如信息的来源和主题等</param>
        private void FaxMag(Object sender,MailManager.MailMagEventArgs e)
        {
            Console.WriteLine("Faxing mail message: " + FaxId);
            Console.WriteLine("From:{0}\n To:{1}\n Subject:{2}\n Body:{3}\n", e.from, e.to, e.subject, e.body);
        }

        //取消注册事件方法的方法
        public void Unregister(MailManager mm)
        {
            //从MailManager对象de事件成员MailMag中删除事件代理对象,及其代理调用的方法FaxMag
            mm.MailMag -= new MailManager.MailMagEventHandler(FaxMag);
        }
    }

    class MailApp
    {
        static void Main(string[] args)
        {
            Console.WriteLine("代理与事件的应用");
            //创建邮件管理器的对象
            MailManager mm = new MailManager();
            //创建传真机等接收器的对象
            Fax f1 = new Fax(mm);
            f1.FaxId = "333333333333";
            //触发事件的信息
            mm.SimulateArrivingMag("TT", "TOM", "代理与事件的应用", "代理是事件处理机制的基础");
            //取消前一个注册的事件
            f1.Unregister(mm);
            //进行下一个E-mail事件
            Fax f2 = new Fax(mm);
            f2.FaxId = "6666666666666";
            //触发事件的信息
            mm.SimulateArrivingMag("TOM", "TT", "已读", "代理与事件的应用");
            Console.ReadLine();

        }
    }
}



0 0