更新时间:2004-12-17
-------------------------------------------------------------------------------
上篇文章说明了控件事件是如何被Dialog触发的,那么我们如何在实际使用中利用这些控件事件呢?我们需要将事件绑定到我们自己的方法。这样,一旦控件事件被触发,我们的程序就会自动调用我们自己的方法来处理该事件。
这样做的好处是显而易见的。试想我们要实现如下的功能:点一个按钮,清除游戏中所有的物体。一般情况下我们是怎么做的?在点按钮的时候再去判断游戏中有多少物体,然后用一个循环销毁它们?这太无聊了,让他们收到命令就自己了断多好(真是听话……)。
所以我们可以在物体创建时,就将按钮的Click事件与该物体的销毁方法绑定,这就是事件驱动的好处啦。DirectX Sample也给我们演示了如何利用事件驱动。比如点击Toggle full screen按钮时触发全屏方法:


疑问:为什么这里的绑定是绑定到EventHandler类型呢?
回答:因为Button的Click事件是EventHandler类型的啊。
疑问:为什么Button的Click事件是EventHandler类型的呢?为什么不能用其他类型?
回答:……这不是在编写《十万个为什么》!!
我们看看上次我们列出来的Button中的代码:













实际上这个EventHandler是一个delegate(委托)方法。
什么叫委托方法呢?
委托方法说白了就是方法本身什么事都不干,你调用的时候才用一个真正干活的方法去实现这个委托。
还是一头雾水……这东西说不白了……
我们还是用上面的代码来说明:
首先给出EventHandler的定义,这个方法是在System命名空间下的,吃白饭的方法:

然后我们知道Button中有这样一行:

这个时候发生了什么事呢?Click就变成了这个委托的一个实现。也就是说调用Click的时候应该是有两个参数的,所以:



这里传了两个参数给Click事件,这两个参数实际上是EventHandler定义的。
到这里都没问题。就像声明了一个类的实例然后调用这个类一样。
可是Click还是什么事都没有干啊?
那当然,Click只是个事件而已,真正干活的在下面:

这就是绑定的代码。OnFullscreenClicked我们用惯了VB或者C#应该都知道,它里面是些什么内容,肯定就是实现全屏的具体代码,要不也是调用实现全屏方法的代码。
那么这个+=是什么意思?
Delegate委托方法是可以用+、-操作来实现多重委托的,就是说吃白饭的头头只有一个,而干活的苦力可以有很多个。这里实际上就是将fullScreen这个按钮的Click委托实现又绑上了一个具体实现:OnFullscreenClicked。想想我们最开始举的例子,我们可以把多个物体的销毁都绑定到一个按钮上,利用的就是这一点。
也就是说一个头头(EventHandler)给下面的小头头(Click)传达任务,小头头(Click)给苦力(OnFullscreenClicked)传达任务,苦力(OnFullscreenClicked)去做任务……
这就是委托的流程,委托最后一定要绑定到一个具体的实现方法,光有任务没人去做是不行的。
明白这个流程后,我们知道EventHandler实际上什么事都没有做,我们完全可以一脚踹开它,自己定义一个委托方法,在Button类的代码前面加上一行:

唔……多了两个字母……
然后在Button中:

这样Click接受的就是MyEventHandler的委托了。
最后再绑定:

小头头(Click)告诉苦力(OnFullscreenClicked):这个任务是新的头头(MyEventHandler)下达的,一定要做好!
疑问:EventHandler和MyEventHandler有啥区别?不还是吃白饭的!?
回答:…………