特殊的委托----事件

时间:2021-08-02 04:30:32
先来了解一下事件是什么. 学习事件之前,要把事件看成委托的一种特殊形式!因为是面向对象在语言层是抽象的,(更高一层就是面向接口,此概念更加抽象化),所以,我们可以想象真实的世界,把现实中的一些东西放大来看本质,比如一个人饿了就需要吃饭,那么就要用很委托去关联”饿了”和”吃饭”这两个动作,一旦”饿了”就触发“吃饭“这个事件,至于如果吃什么东西,如何吃那是响应事件的内容!在.NET世界中,不管是WEB Forms(ASP.NET)还是Windows Forms,都涉及到大量对象的事件响应及处理.有些了解后,让我们来看下一段模拟代码。
 
//**********************************************************************
using System;
 
namespace Test
{
    delegate void HungryHandler();//定义委托
    class Program
    {
        static void Main(string[] args)
        {
            People 小王 = new People();//小王
            小王.HaveDinner += new HungryHandler(小王_HaveDinner);//关联动作和事件
            小王.HungryAction();//激发事件
            Console.ReadLine();//此语句无用,只是让屏不一闪而过.
        }
 
        static void 小王_HaveDinner()//响应事件的函数,也就是响应事件该做的
        {
            Console.WriteLine("该吃饭了");//输出
        }
    }
 
    class People //实例类
    {
        public event HungryHandler HaveDinner;
        public void HungryAction()
        {
            if (HaveDinner != null)
                HaveDinner();//调用委托关联事件函数,在这是调用”小王_HaveDinner”
        }
       
    }
}
//**********************************************************************
程序输出结果为:
该吃饭了
 
这个例子应该不是你见过最复杂的代码吧。呵呵。如果上面这个例子没有问题的话 , 那么现在让我们一起来实现类似于 winform 事件的程序 . 当然只要有事件,委托的定义就是必须的!
 
//**********************************************************************
using System;
 
namespace Test
{
    delegate void HungryHandler(object sender, EventArgs e);//定义委托
    class Program
    {
        static void Main(string[] args)
        {
            People 小王 = new People("小王");//小王实例类名称
            小王.HaveDinner += new HungryHandler(小王_HaveDinner);//关联动作函数和事件
            小王.HungryAction(小王.Name,new EventArgs ());//激发事件
            Console.ReadLine();//此语句无用,只是让屏不一闪而过.
        }
 
        static void 小王_HaveDinner(object sender, EventArgs e)//响应事件的函数,也就是响应事件该做的
        {
            Console.WriteLine(((People)sender).Name+"该吃饭了");
        }
    }
 
    class People //实例类
    {
        private string name;
        public People(string name)
        {
            this.name = name;
        }
        public event HungryHandler HaveDinner;
       
        public void HungryAction(object sender,EventArgs e)
        {
            if (HaveDinner != null)
                HaveDinner(this, e); //关联跟委托挂构的函数.在此程序中是调用"小王_HaveDinner";
        }
        public string Name
        {
            get { return name; }
        }
    }
}
//**********************************************************************
程序输出结果为:
小王该吃饭了
 
此段程序可能相对要复杂一些,但是只要是上段程序没有问题的话,仔细结合注释来看这段程序,就没有什么问题了。当然,有时候我们在windows看到一些事件不是关联的参数,有大部份都不是EventArgs类。但是有时候你却发现的事件处理函数参数还有其它的一些类,不单单只有EventArgs,如MouseEventArgs, KeyPressEventArgs, MouseEventArgs, FormClosedEventArgs,这此类其实都是从系统类EventArgs类派生出来的类。只要我们愿意或是实际的项目需要,完全可以做一个自已事件参数类,当然也要继承EventArgs啦,但这不是在此不是必须的。如果是继承窗体和控件的话,那就是必要条件。呵呵。关于继承和多态,就要看大家的需要了,如果博客里的评论反应情况了,如果反映多的话,我会在以后的章节把这几点加上去的。好的,现在就让我们一起来对上面的程序进行扩充,来实现这一点。请看下面的程序:
//*************************************************************************************************************
 
using System;
 
namespace Test
{
    delegate void HungryHandler(object sender, HungryEventArgs e);//定义委托 ,请记住是实现事件的基础,请注意 EventArgs 已改为 HungryEventArgs
   
    class Program
    {
        static void Main(string[] args)
        {
            People 小王 = new People("小王");//小王实例类名称
           
            小王.HaveDinner += new HungryHandler(小王_HaveDinner);//关联动作函数和事件
            小王.HungryAction(null, new HungryEventArgs("还好"));//即便传null,照样可以响应,因为事件在HungryAction函数中已经用了this,this是用来指当前类实例对象的属性,变量和方法,不包括静态所有成员.你也可以用"小王"代替它,效果是一样的.
           
            Console.ReadLine();//此语句无用,只是让屏不一闪而过.
        }
 
        static void 小王_HaveDinner(object sender, HungryEventArgs e)//响应事件的函数,也就是响应事件该做的
        {
            switch (e.State)
            {
                case "很饿":
                    Console.WriteLine(((People)sender).Name + e.State + "-------该吃饭了");
                    break;
                case "还好":
                    Console.WriteLine(((People)sender).Name + e.State + "-------可以晚点吃");
                    break;
                default:
                    Console.WriteLine(((People)sender).Name + e.State + "-------不想吃");
                    break;
            }
        }
    }
 
    class People //实例类
    {
        private string name;
        private string sex;
 
       public People(string name)
        {
            this.name = name;
        }
        public event HungryHandler HaveDinner; // 定义事件
 
        public void HungryAction(object sender, HungryEventArgs e)
        {
            if (HaveDinner != null)
                HaveDinner(this, e); //请注意this的作用是返回实例的对象,关联跟委托挂构的函数.在此程序中是调用"小王_HaveDinner";
        }
        public string Name
        {
            get { return name; }
        }
    }
   
    class HungryEventArgs : EventArgs   //注意此处继承了EventArgs
    {
        private string state;
        public HungryEventArgs(string state)
        {
            this.state = state;
        }
        public string State
        {
            get { return state; }
        }
    }
}
 
程序输出结果为:
小王还好-------可以晚点吃"
//*************************************************************************************************************
好的,以上都是一些事件的基础知识,如有讲得不对的地方还请大家见谅。这段时间可能写博客的时间要少了,因为要用做UML去架构一个新的工程了。空闲时间会比较少了,当然如果我有空的话,我还是会尽快更新博客的,同时也希望读完我的文章的朋友,在评论里面留言给我,各方面的意见的可以,也可以是希望下一期的内容,我得到反馈信息后,会根据实际情况来按排,只有这样才可以这个的博客做得更好,更贴近实际的开发。