前一个Post当中介绍了WPF如何处理事件的传递过程。如何定义传递事件,并且对事件进行了分类。现在,我们看看WPF到底是如何处理Bubbling和Tunneling事件的。最后介绍了Attached事件。 Tunneling事件的好处就是可以有机会改变或者取消后面的Bubbling事件。WPF内建的响应事件只会对Bubbling事件进行响应,当然,前提了Bubbling和Tunneling同时定义。这种行为有什么好处呢?看下面的一个例子:比如,我们想实现一种特殊的编辑框,只允许输入一些特定的字符。以前的实现方法在处理编辑框的KeyDown或者编辑框的WM_CHAR事件,然后判断新输入的字符是否满足条件,如果不满足,我们再把编辑框的值设置为原来的值。这种实现技术会有字符的一个回退过程。而在WPF中,实现方法不同,直接在PrevewKeyDown等Tunneling事件中处理,如果是不需要的字符,把事件设置为已经处理过。这样这个事件就不会进入到后面的Bubbling事件KeyDown中,WPF也根本不会显式这个字符。这种方法的效果将比之前的回退处理好很多。 虽然我们可以通过RoutedEventArgs参数的Handled属性为True来终止事件的传递。但是,有时候我们需要某个事件始终被接受处理,这可以通过程序代码实现。使用重载的AddHanlder方法。比如,我们给窗口添加一个鼠标右键的处理方法(其中MRBD_Handler是类的一个事件方法): public AboutDialog() 这样,任何条件下,MRBD_Handler都可以接收到窗口的鼠标右键事件。即使鼠标右键是点击在窗口中的某个子控件之上。 【Attached事件】 与Attached属性类似,WPF的Element在事件没有定义的情况下也支持Tunneling或者Bubbling事件。比如,我们可以在一个简单的窗口程序中这样指定事件函数: 例子中,因为Window本身没有定义Click事件,所以我们必须指定Click事件属性的名称前缀,也就是定义事件的类名。经过这样的定义后,点击在Window中的TestButton,也会激发属性声明的Click事件,调用对应的Button_Click方法。 为什么这样的定义可以通过呢?首先编译时,XAML会看到Button类确实定义了一个Click的.NET事件。在运行时,会直接调用AddHandler把这两个事件依附到Window对应的类当中。所以上面用XAML属性声明的事件代码与下面的程序代码等效: public Window1 |
|