• 委托与事件——事件


      上接”委托与事件——委托“,为了维护程序的封装性,事件不得不出场。

      关键字event,用来声明事件对象,允许一个类或对象提供通知的成员,他必须是委托类型。

      事件是类和对象向外界发出的消息,事件的执行是通过事件委托的方式,事件的类型是委托类型。调用我们所准备好的处理方法,要响应某些事件并针对某些事件执行我们指定的方法,需要做到以下几步:

    1、声明事件委托。

    2、声明事件。—————————怎么声明事件

    3、添加事件的触发方法。——————这个事件在什么情况下会被触发

    4、添加事件的处理程序(响应事件的方法)。————————怎么处理这个事件

    5、将指定的事件处理程序绑定到要处理的事件上(订阅事件)。—————谁来处理

    6、用户信息操作,并触发事件(调用事件的触发方法)。

    7、通过事件委托的回调,执行我们需要的事件处理程序。

    所以要想让事件能够正常运转,我的程序中必须存在以下三者:

          事件发送者、事件接收者、事件本身

      只能对事件进行“+=”和“-=”操作,不可以对事件进行赋值“=”操作。所以引用事件的目的,就是为了封装。

      在我们进行winform编程的时候,我们经常用到按钮Button的重要事件:Click,

            //处理事件的方法,被定义成委托
            public delegate void EventHandler(object sender, EventArgs e);
            //单机按钮的时候发生的事件
            public event EventHandler Click;
            
            //订阅事件,将事件处理程序绑定到要处理的事件上
            btn.Click += new EventHandler(btn_MyClick);
    
            //这个是我们点击的按钮之后,所执行的方法
            private void btn_MyClick(object sender, EventArgs e)
            {
                Button btn = sender as Button;
                MessageBox.Show("你点击了" + btn.Text);
            }

      下面我们来编写程序,自己定义一个事件,然后触发这个事件,再进行处理

      这是一个监听键盘按键的事件,会把我们按下的键的字符显示出来。

      1 /*TestEventSource类。他就相当于windows控件类一样,是事件的源,里面包含有事件的声明,
      2  * 以及存储调用参数的事件参数类,以及事件的触发方法。      
      3 
      4 TestEventListener类。他提供了事件处理程序,并实现了事件处理程序和事件对象的邦定,
      5  * 当然时间处理程序可以放在别处, 跟邦定程序(订阅事件)放在一起便于理解和调用
      6 
      7 Test 类,实例化自定义事件的事件源对象,并调用 TestEventListener类中的Subscribe(es);
      8  * 方法进行事件对象和事件处理程序的邦定(订阅事件),调用 TestEventSource类中的
      9  * RaiseEvent(char keyToRaiseEvent)引发对象,并有对象所指定的委托回调处理事件。
     10  * 完成整个自定义事件。
     11 
     12 其中   RaiseEvent(char keyToRaiseEvent)      就相当于main()一样是自定义事件的执行入口,      
     13  * 从这个法开始---〉调用事件委托----〉查找订阅事件程序找到事件所封装的方法集----〉
     14  * 由委托回调事件处理程序并传递参数---〉执行事件处理程序。
     15  */
     16 namespace event事件
     17 {
     18     //发布事件的类
     19     public class TestEventSource 
     20     {
     21         //定义事件参数类
     22         public class TestEventArgs : EventArgs 
     23         {
     24             public readonly char KeyToRaiseEvent;
     25             public TestEventArgs(char keyToRaiseEvent) 
     26             {
     27                 KeyToRaiseEvent = keyToRaiseEvent;
     28             }
     29         }
     30 
     31         //定义delegate
     32         public delegate void TestEventHandler(object sender, TestEventArgs e);
     33 
     34         //用event关键字声明事件对象
     35         public event TestEventHandler TestEvent;
     36 
     37         //事件触发方法
     38         protected virtual void OnTestEvent(TestEventArgs e) 
     39         {
     40             if (TestEvent != null)
     41             {
     42                 TestEvent(this, e);
     43             }
     44         }
     45 
     46         //引发事件
     47         public void RaiseEvent(char keyToRaiseEvent) 
     48         {
     49             TestEventArgs e = new TestEventArgs(keyToRaiseEvent);
     50             OnTestEvent(e);
     51         }
     52     }
     53 
     54     //监听事件的类
     55     public class TestEeventListener 
     56     {
     57         //定义处理事件的方法,它与声明事件的delegate具有相同的参数和返回值类型
     58         public void keyPressed(object sender, TestEventSource.TestEventArgs e) 
     59         {
     60             Console.WriteLine("发送者:{0},所按的键为:{1}",sender,e.KeyToRaiseEvent);
     61         }
     62 
     63         //订阅事件
     64         public void Subscribe(TestEventSource eventSource) 
     65         {
     66             eventSource.TestEvent += new TestEventSource.TestEventHandler(keyPressed);
     67         }
     68 
     69         //取消订阅事件
     70         public void UnSubscribe(TestEventSource eventSource)
     71         {
     72             eventSource.TestEvent -= new TestEventSource.TestEventHandler(keyPressed);
     73         }
     74     }
     75 
     76     class Program 
     77     {
     78         public static void Main() 
     79         {
     80             //创建事件源对象
     81             TestEventSource es = new TestEventSource();
     82 
     83             //创建监听对象
     84             TestEeventListener el = new TestEeventListener();
     85 
     86             //订阅事件
     87             Console.WriteLine("订阅事件
    ");
     88             el.Subscribe(es);
     89 
     90             //引发事件
     91             Console.WriteLine("输入一个字符,再按enter键");
     92             string s = Console.ReadLine();
     93             es.RaiseEvent(s.ToCharArray()[0]);
     94 
     95             //取消订阅事件
     96             Console.WriteLine("
    取消订阅事件
    ");
     97             el.UnSubscribe(es);
     98 
     99             //引发事件
    100             Console.WriteLine("输入一个字符,再按enter键");
    101             s = Console.ReadLine();
    102             es.RaiseEvent(s.ToCharArray()[0]);
    103         }
    104     }
    View Code

      当我们取消订阅事件后,再来引发事件,就不会再执行处理事件的方法了。

  • 相关阅读:
    如何通过地址转换为WGS经纬度
    Oracle动态创建时间分区,以及Oracle12c中快速创建自增列
    asp.net微信jsapi支付
    asp.net关于如何准许api跨域访问
    ajax调用天气接口
    git补充(命令)转自https://github.com/Wasdns/github-example-repo
    git补充(关于pull request)转自知乎
    Linux基础笔记
    git前期准备
    MVC设计模式
  • 原文地址:https://www.cnblogs.com/lcxBlog/p/4495964.html
Copyright © 2020-2023  润新知