标签:
上接”委托与事件——委托“,为了维护程序的封装性,事件不得不出场。
关键字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("订阅事件\n"); 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("\n取消订阅事件\n"); 97 el.UnSubscribe(es); 98 99 //引发事件 100 Console.WriteLine("输入一个字符,再按enter键"); 101 s = Console.ReadLine(); 102 es.RaiseEvent(s.ToCharArray()[0]); 103 } 104 }
当我们取消订阅事件后,再来引发事件,就不会再执行处理事件的方法了。
标签:
原文地址:http://www.cnblogs.com/lcxBlog/p/4495964.html