C#的基础琐碎总结-----事件

1、 事件简单理解

  可以理解为对象对外部情况作出相应的响应,如:用户在UI中单击自定义控件时,该控件会触发click事件。

2、 事件的工作方式

(1)首先,必须在类中声明事件并确定将要使用的委托和参数

(2)其次必须定义在触发事件时要调用的委托

(3)最后,必须设计事件参数类,该参数类的实例会将信息传递给调用的方法

理解以上三点可以用这个例子:小孩子玩气球(气球类),气球有最大容积当充气超出容积会爆炸(爆炸事件),当小孩听到爆炸声吓哭了。

class Program

    {      

        //第一步:类外面定义委托,使用类发生事件时外部可以根据本委托处理事件

 

        public delegate void 爆炸EventHandler();//事件处理程序 

 

        public class Balloon

        {

            private readonly int _Max容积;

            private int _当前容积;

            public int 最大容积

            {

                get { return this._Max容积; }

            }

            //构造函数

            public Balloon(int 最大容积)

            {

                this._Max容积 = 最大容积;

            } 

            //第二步:在类的内部,定义该类具有那个事件

            //调用事件时,必须判断事件是否为空

            public  event  爆炸EventHandler  爆炸event;//事件关键字+委托名+事件名

            //充气方法

            public void 充气(int 充气体积)

            {

                this._当前容积 += 充气体积;

                if (this._当前容积>this.最大容积)

                {

                    //触发爆炸事件,并通知别人气球爆炸了

                    //判断是不是有注册过事件的处理程序

                    //第三步:激发事件

                    if (this.爆炸event!=null)

                    {

                            this.爆炸event();                       

                    }                   

                }

            }    

     }

        public class 小孩

        {

            private Balloon _ball;

           

            public 小孩(Balloon ball)

            {

                this._ball = ball;

                //第四步:注册事件

                //注册事件的处理程序,小孩会处理打气事件

                //注册:事件源名+=new 时间委托类型(事件处理方法);            

                this._ball.爆炸event += new 爆炸EventHandler(this.听到气球爆炸);

                this._ball.爆炸event += new 爆炸EventHandler(_ball_爆炸event);                    

            }

           //第五步:实现事件发生时要调用的方法(通俗的说事件触发时候该做什么)

            void _ball_爆炸event()

            {

                Console.WriteLine("小孩子吓哭了!");

            }

            public void 打气(int m)

            {

                this._ball.充气(m);

            }

            public void 听到气球爆炸()

            {

                Console.WriteLine("处理者:气球爆炸了");

            }

        }

        static void Main(string[] args)

        {

            Balloon ball = new Balloon(20);

            小孩 boy1 = new 小孩(ball);

            boy1.打气(5);

            boy1.打气(5);

            boy1.打气(5);

            boy1.打气(5);

            boy1.打气(5);       

        }

}

通过以上可总结出:使用事件的一般步骤(以上例为例子):

第一步:定义处理事件的委托,也即事件的处理程序;

 如:public delegate void 爆炸EventHandler();

第二步:在类的内部定义事件,指定事件处理的委托类型,也即定义事件

  如: public event 爆炸EventHandler 爆炸event;//事件关键字+委托名+事件名

第三步:在类内部在适当的时候触发事件,通俗的说是调用事件,类似于调用委托;

        如:if (this._当前容积>this.最大容积)

            {    

                    if (this.爆炸event!=null)

                    {

                        this.爆炸event();                       

                    }

} 

第四步:再类的外部(也可以在内部)注册类的事件处理程序。

//注册:事件源名+=new 时间委托类型(事件处理方法);

this._ball.爆炸event += new 爆炸EventHandler(this.听到气球爆炸);

this._ball.爆炸event += new 爆炸EventHandler(_ball_爆炸event);

第五步:实现事件触发时要处理的方法,如this.听到气球爆炸()和_ball_爆炸event();

3、  简单的事件原理我们应该通过上面的例子明白了,下面我们深入了解下:(简单介绍小时间参数类EventArgs)

加入我们还以上例子为标准,我们提出这样一个需求:小孩子吓哭的同时想知道爆炸的时间?该如何解决?

其实很简单,只需在注册事件委托时候加入一个需要的参数即可,改动的地方如下:

       public delegate void 爆炸EventHandler(DateTime dt);

            void _ball_爆炸event(DateTime dt)

            {

                Console.WriteLine("小孩子吓哭了!");

            }

            public void 打气(int m)

            {

                this._ball.充气(m);

            }

            public void 听到气球爆炸(DateTime dt)

            {

                Console.WriteLine("处理者:气球爆炸了,爆炸时间是:{0}",dt);

            }

显然这个问题解决了,那么加入又增加了需求,不仅要知道气球爆炸的时间还想知道,爆炸的地点等,那么我们还需继续改动,若以后有更多的参数,我们就得不断地改动很多地方,岂不是很累?那么该怎么办呢?很显然,利用面向对象的思想,把委托的参数抽象成一个类,即可解决,也即形成了所谓的事件参数类。

//事件参数类

public class BalloonEventArgs

     {

            private DateTime dt; 

            public DateTime Dt

            {

                get { return dt; }

                set { dt = value; }

            }

            private string address; 

            public string Address

            {

                get { return address; }

                set { address = value; }

            }

            public BalloonEventArgs(DateTime dt1, string add)

            {

                this.Dt = dt1;

                this.address = add;               

            }

   }

这样以后如果再有什么参数要加入,直接修改类里面的字段即可,不必修改每个委托参数和方法。完整代码如下:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text; 

namespace ConsoleApplication1

{

    class Program

    {

        public delegate void 爆炸EventHandler(BalloonEventArgs e);

        public class Balloon

        {

            private readonly int _Max容积;

            private int _当前容积;

            public int 最大容积

            {

                get { return this._Max容积; }

            }

            //构造函数

            public Balloon(int 最大容积)

            {

                this._Max容积 = 最大容积;

            }

           public event 爆炸EventHandler 爆炸event;

           public void 充气(int 充气体积)

            {

                this._当前容积 += 充气体积;

                if (this._当前容积 > this.最大容积)

                {

                  

              if (this.爆炸event != null)

              {

                 BalloonEventArgs arg = new BalloonEventArgs(DateTime.Now, "南阳理工学院");

                  this.爆炸event(arg); 

               } 

          }

            } 

        }

        public class 小孩

        {

            private Balloon _ball; 

            public 小孩(Balloon ball)

            {

                this._ball = ball;

                this._ball.爆炸event += new 爆炸EventHandler(this.听到气球爆炸);

                this._ball.爆炸event += new 爆炸EventHandler(_ball_爆炸event);

 

            } 

            void _ball_爆炸event(BalloonEventArgs e)

            {

                Console.WriteLine("小孩子吓哭了!");

            }

            public void 打气(int m)

            {

                this._ball.充气(m);

            }

            public void 听到气球爆炸(BalloonEventArgs e)

            {

                Console.WriteLine("处理者:气球爆炸了,爆炸时间是:{0},爆炸地点是:{1}",e.Dt,e.Address);

            }

        }

        public class BalloonEventArgs

        {

            private DateTime dt; 

            public DateTime Dt

            {

                get { return dt; }

                set { dt = value; }

            }

            private string address; 

            public string Address

            {

                get { return address; }

                set { address = value; }

            }

            public BalloonEventArgs(DateTime dt1, string add)

            {

                this.Dt = dt1;

                this.address = add;

               

            }

        }

        static void Main(string[] args)

        {

            Balloon ball = new Balloon(20);

            小孩 boy1 = new 小孩(ball);

            boy1.打气(5);

            boy1.打气(5);

            boy1.打气(5);

            boy1.打气(5);

            boy1.打气(5);

        }

    }

 

}

posted @ 2012-01-03 10:26  GavinJune  阅读(414)  评论(0编辑  收藏  举报