事件(event) 这个词儿对于初学者来说 往往总是显得有些神秘 不易弄懂 而这些东西却往往又是编程中常用且非常重要的东西 大家都知道windows消息处理机制的重要 其实C#事件就是基于windows消息处理机制的 只是封装的更好 让开发者无须知道底层的消息处理机制 就可以开发出强大的基于事件的应用程序来
先来看看事件编程有哪些好处
在以往我们编写这类程序中 往往采用等待机制 为了等待某件事情的发生 需要不断地检测某些判断变量 而引入事件编程后 大大简化了这种过程
使用事件 可以很方便地确定程序执行顺序
当事件驱动程序等待事件时 它不占用很多资源 事件驱动程序与过程式程序最大的不同就在于 程序不再不停地检查输入设备 而是呆著不动 等待消息的到来 每个输入的消息会被排进队列 等待程序处理它 如果没有消息在等待 则程序会把控制交回给 *** 作系统 以运行其他程序
事件简化了编程 *** 作系统只是简单地将消息传送给对象 由对象的事件驱动程序确定事件的处理方法 *** 作系统不必知道程序的内部工作机制 只是需要知道如何与对象进行对话 也就是如何传递消息
有了这么多好处 看来我们的确有必要掌握它 俗话说 难了不会 会了不难 就让我们一步一步开始吧
要讲事件 必然要讲到委托(delegate) 它们之间的关系可以通过一个浅显的比方来说明 这个比方可能不是十分恰当 比如你要租一个房屋 这是一个事件 那么委托就是房屋租赁中介 当你把租房子的消息告知中介后 中介就会产生出一套符合你要求的房屋租赁方案来 再由中介执行这套方案 你便租得了这个房屋 即事件被处理了 当然你也可以不通过中介 直接找房东 但如果没有互联网等工具 你如何得到谁出租房屋的信息?话题扯远了
委托(delegate)
委托可以理解成为函数指针 不同的是委托是面向对象 而且是类型安全的 关于委托的理解 可以参考我的另一篇文章《C#委托之个人理解》
事件(event)
我们可以把事件编程简单地分成两个部分 事件发生的类(书面上叫事件发生器)和事件接收处理的类 事件发生的类就是说在这个类中触发了一个事件 但这个类并不知道哪个个对象或方法将会加收到并处理它触发的事件 所需要的是在发送方和接收方之间存在一个媒介 这个媒介在 NET Framework中就是委托(delegate) 在事件接收处理的类中 我们需要有一个处理事件的方法 好了 我们就按照这个顺序来实现一个捕获键盘按键的程序 来一步一步说明如何编写事件应用程序
首先创建一个自己的EventArgs类
引自MSDN:
EventArgs是包含事件数据的类的基类 此类不包含事件数据 在事件引发时不向事件处理程序传递状态信息的事件会使用此类 如果事件处理程序需要状态信息 则应用程序必须从此类派生一个类来保存数据
因为在我们键盘按键事件中要包含按键信息 所以要派生一个KeyEventArgs类 来保存按键信息 好让后面知道按了哪个键
internal class KeyEventArgs : EventArgs{ private char keyCharpublic KeyEventArgs( char keyChar ) : base() { this keyChar = keyChar} public char KeyChar { get { return keyChar } }}
再创建一个事件发生的类KeyInputMonitor 这个类用于监控键盘按键的输入并触发一个事件
internal class KeyInputMonitor{ // 创建一个委托 返回类型为void 两个参数 public delegate void KeyDown( object sender KeyEventArgs e )// 将创建的委托和特定事件关联 在这里特定的事件为OnKeyDown public event KeyDown OnKeyDownpublic void Run() { bool finished = falsedo { Console WriteLine( Input a char ) string response = Console ReadLine() char responseChar = ( response == ) ? : char ToUpper( response[ ] ) switch( responseChar ) { case X : finished = true break default: // 得到按键信息的参数 KeyEventArgs keyEventArgs = new KeyEventArgs( responseChar ) // 触发事件 OnKeyDown( this keyEventArgs ) break } }while( !finished )}}
这里注意OnKeyDown( this KeyEventArgs )一句 这就是触发事件的语句 并将事件交由KeyDown这个委托来处理 委托指定事件处理方法去处理事件 这就是事件接收方的类的事情了 参数 this是指触发事件的对象就是本身这个对象 keyEventArgs包含了按键信息
最后创建一个事件接收方的类 这个类先产生一个委托实例 再把这个委托实例添加到产生事件对象的事件列表中去 这个过程又叫订阅事件 然后提供一个方法回显按键信息
internal class EventReceiver{ public EventReceiver( KeyInputMonitor monitor ) { // 产生一个委托实例并添加到KeyInputMonitor产生的事件列表中 monitor OnKeyDown += new KeyInputMonitor KeyDown( this Echo )} private void Echo(object sender KeyEventArgs e) { // 真正的事件处理函数 Console WriteLine( Capture key: { } e KeyChar )}}
看一下如何调用
public class MainEntryPoint{ public static void Start() { // 实例化一个事件发送器 KeyInputMonitor monitor = new KeyInputMonitor() // 实例化一个事件接收器 EventReceiver eventReceiver = new EventReceiver( monitor ) // 运行 monitor Run()}}
总结
C#中使用事件需要的步骤
创建一个委托
将创建的委托与特定事件关联( Net类库中的很多事件都是已经定制好的 所以他们也就有相应的一个委托 在编写关联事件处理程序 也就是当有事件发生时我们要执行的方法的时候我们需要和这个委托有相同的签名)
编写事件处理程序
利用编写的事件处理程序生成一个委托实例
把这个委托实例添加到产生事件对象的事件列表中去 这个过程又叫订阅事件
C#中事件产生和实现的流程
定义A为产生事件的实例 a为A产生的一个事件
定义B为接收事件的实例 b为处理事件的方法
A由于用户(程序编写者或程序使用者)或者系统产生一个a事件(例如点击一个Button 产生一个Click事件)
A通过事件列表中的委托对象将这个事件通知给B
B接到一个事件通知(实际是B b利用委托来实现事件的接收)
lishixinzhi/Article/program/net/201311/15725c c++并没有event功能。
不过一些事件循环框架 例如windows 的核心库和qt这类是有event的。 还有很多项目也用到event这个概念,这个玩意就是设计上的一个概念, 一般来说是用来降低耦合的, 比如我写了一个模块用来做IO, 成功后会发一个event, coordinator收到这个event会调用其他业务逻辑模块来做一些 *** 作。 这种设计在C语言项目中比较多, 因为C语言的项目层次结构一般比较散比较平, 不太好做成层次结构, 需要消息队列这类手段来协调各种功能。
EventHandler即事件委托,表示用于处理不具有事件数据的事件的方法。
字面上理解就是一个事件处理器,将一个事件与处理事件的方法联系起来的一种机制。
C++中通过函数指针来完成的。
在C#中的事件基于委托模型。委托模型遵守观察者设计模式,使订阅者(接收或处理事件的类)能够向提供方(发送或引发事件的类)注册并接收相关通知。
步骤:
首先声明一个委托,一般命名为:NameEventHandler
// 这些委托没有返回类型值,并且接受两个参数(事件源的对象和事件数据的对象)。
public delegate void ThresholdReachedEventHandler(object sender, ThresholdReachedEventArgs e)
然后声明一个事件,并指定事件的委托类型
// event关键字代表事件,返回类型为委托;
public event EventHandler 事件名
同时,创建引发事件的方法,一般命名为:OnEventName。
// 通常为了引发事件,会添加一个标记为protected和virtual的方法,以允许派生类重写引发事件的逻辑。
protected virtual void OnThresholdReached(EventArgs e)
{
EventHandler handler = ThresholdReached
if (handler != null)
{
handler(this, e)
}
}
再定义一个事件处理程序方法,处理事件。
static void c_ThresholdReached(object sender, EventArgs e)
{
Console.WriteLine("The threshold was reached.")
}
最后使用加法赋值运算符 (+=) 来为事件附加事件处理程序。+=表示添加事件,-=表示删除事件。
// Counter类中需要拥有一个名为ThresholdReached的事件
Counter c = new Counter()
c.ThresholdReached += c_ThresholdReached
// 以下是老的C#1.0的语法
// c.ThresholdReached += new ThresholdReachedEventHandler(c_ThresholdReached)
以下是C# EventHandler委托的一个类比解释
例子:
this.Activated += new EventHandler(Form1_Activated)
这是一个委托的原理.
this.Activated=你吃完饭
Form1_Activated=喊我一声
意思就是把这两个事放在一起,意思就是叫你吃完饭了喊我一声。我委托你吃完饭了,喊我一声。这样我就不用过一会就来看一下你吃完了没有了,已经委托你了。
扩展资料:语法
Visual Basic(声明)
<SerializableAttribute>_
<ComVisibleAttribute(True)>_
Public Delegate Sub EventHandler ( _
sender As Object, _
e As EventArgs _
)
Visual Basic(用法)
Dim instance As New EventHandler(AddressOf HandlerMethod)
C#
[SerializableAttribute]
[ComVisibleAttribute(true)]
public delegate void EventHandler (
Object sender,
EventArgs e
)
C++
[SerializableAttribute]
[ComVisibleAttribute(true)]
public delegate void EventHandler (
Object^ sender,
EventArgs^ e
)
参考资料:
百度百科——EventHandler
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)