• 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);

            }

        }

     

    }

  • 相关阅读:
    【转】ImageView的Scaletype参数设置
    android抓包工具——使用fiddler4在安卓手机抓包
    Java中JNI的使用详解第一篇:HelloWorld
    A/libc:fatal signal 11(SIGSEGV).code 1, fault addr 0x0 in tid 26488 (VideoEncoder)
    Android修改默认SharedPreferences文件的路径,SharedPreferences常用工具类
    android下asynchttp库对于session的支持
    routeros的配置资料
    Mac下关于——你不能拷贝项目“”,因为它的名称太长或包括的字符在目的宗卷上无效。文件的删除
    nginx的https配置
    ros的相关link
  • 原文地址:https://www.cnblogs.com/fuchongjundream/p/2310832.html
Copyright © 2020-2023  润新知