做windows编程总要想办法处理事件,例如捕捉按钮的双击事件、处理菜单项的单击事件、对Label上的鼠标的移动作出反映等。但是怎样在自定义的控件中创建自定义的事件呢?通过这篇文章,你将学会怎样使用观察者模式(Observer design pattern )激发并处理 .NET 控件的事件,学习C#自定义事件,并学会传递事件参数。
事件是对象发出的消息,它通知其它对象动作的发生。动作可以是用户激发的,如鼠标点击,也可以由一些程序逻辑激发。产生事件的对象称为事件发送者,接受事件通知的对象称为事件接收者。事件接收者有能够对事件作出反映的方法。
.NET Framework 能够很容易地实现事件驱动的window编程。程序开发人员无需了解.NET的事件是 如何工作的。我们需要记住的是:如果你想要从window控件获取事件,你提供一Event Handler,然后将它注册到事件源,这就是事件编写。在C#中,语法如下,通常都写在Form的构造方法中。
- eventSource.someEvent += new SomeEventHandler(someMethod);
以处理button1控件的Click事件为例,但Click事件发生时将执行button1_Clicked方法。你可以这样写:
- button1.click+=new EventHandler(button1_Clicked);
然后button1_Clicked方法的实现如下:
- private void button1_Clicked(Object sender,EventArgs e)
- {
- //code to be executed when the Click event occurs
- }
这个方法并非必须为private,但是它必须接受两个参数:一个是Object 对象,另一个是EventArgs 对象。所以我们可以假设事件是一块蛋糕。接下来我门来看看怎样创建自定义事件以让其它程序员来使用。在这之前,我们来讨论对象编程中的观察者模式。
观察者模式(Observer Pattern)
观察者模式有两个重要的对象:观察主体和观察者。每个观察主体有一到多个观察者。这些观察者监听来自观察主题状态变化的通知。观察者模式也叫做依赖模式或发布—订阅模式。四人帮(Erich Gamma、Richard Helm、Ralph Johnson、John Vlissides)在他们写的《Design Patterns:Elements of Reusable Object-Oriented Software》书中提到观察者模式可以应用在以下几种场合:
一个抽象有两个方面,这两个方面彼此依赖。将这两个方面封装在不同的对象中,这样你就可以独立地修改和重用它们。
一个对象的改变需要改变其它对象,并且有多少对象需要随之改变未知。
一个对象需要通知其它对象,但并不知道要通知哪些对象。换言之,你并不希望这些对象被紧紧地捆绑在一起。
事件通信时,事件发生者并不知道哪些对象或方法将收到市静安发生的通知,它只是持有与签名符合的方法的引用。代理相当于类项安全的函数指针或者回调。接下来我们将解释怎样使用代理来传递事件消息。再然后我们将通过一个拥有两个自定义控件的例子将理论应用于实际。
c#自定义事件步步通
假定你要为自定义控件MyControl写自定义事件MyEvent,其中MyControl扩展自System.Windows.Forms.UserControl。以下是关键步骤:
1. 声明公有的delegate,这里我们命名为MyEventHandler。MyEventHandler有两个参数。Object对象sender和MyEventArgs对象e。关于MyEventArgs我们将在后面定义。需要注意的是delegate必须声明在你的自定义控件之外。
- public delegate void MyEventHandler(object sender,MyEventArgs e);
- public class MyControl:UserControl
- {
- ……
- }
2. 1中的MyEventArgs是这样一个对象,它持有由事件发生者传递给事件接收者的数据。MyEventArgs必须继承自System.EventArgs。这时的代码如下:
- public class MyEventArgs:System.EventArgs
- {
- ……
- }
- public delegate void MyEventHandler(object sender,MyEventArgs e);
- public class MyControl:UserControl
- {
- ……
- }
需要在MyEventArgs类中写一些具体实现。这一点我们会在以后讲到。
3. 在自定义控件类中,声明一个事件,声明为MyEvent。
- public class MyEventArgs:System.EventArgs
- {
- ……
- }
- public delegate void MyEventHandler(object sender,MyEventArgs e);
- public class MyControl:UserControl
- {
- public event MyEventHandler MyEvent;
- ……
- }
4. 在自定义控件类中,声明受保护的虚方法,命名规则是在事件名字的前面加上On。既然我们的事件命名为MyEvent,那么这个方法就叫做OnMyevent。OnMyevent方法有一个MyEventArgs类型的参数。这个方法用来生成事件。在c#中直接调用事件名字来生成事件。生成事件需要传递两个参数:事件发生者和传递给方法的参数MyEventArgs。
- public class MyEventArgs:System.EventArgs
- {
- ……
- }
- public delegate void MyEventHandler(object sender,MyEventArgs e);
- public class MyControl:UserControl
- {
- public event MyEventHandler MyEvent;
- protected virtual void OnMyEvent(MyEventArgs e)
- {
- MyEvent(this,e);
- }
- ……
- }
最后一步就是在自定义控件类中实际地调用OnMyEvent。
这样,c#自定义事件的步骤就完成了。
【编辑推荐】