在实用WPF时,一般情况下都会碰到有关WPF事件的相关应用。那么首先我们需要了解的就是一些获得支持的WPF事件策略。其中主要包括三种WPF事件策略:#t#
Tunneling:事件首先在根元素激发,然后到达树下的每个元素直到源元素(或者有处理函数处理这个事件终止了传递)。
Bubbling:事件首先在源元素激发,然后向上直到根元素(或者有处理函数处理这个事件终止了传递。
Direct:事件只在源元素激发。这与普通的.NET事件一样,除了参与事件触发器。
在上面的WPF事件策略例子中,我们注册的事件策略就是Bubbling。
传递事件的处理函数的参数与普通.NET事件一样。第一个参数System.Object表示处理函数依附的元素。第二个的System.EventArgs派生类,提供了如下四个有用的属性:
Source:逻辑树中激发事件的原始元素。
OriginalSource:视觉树中激发事件的原始元素。
Handled:布尔值,表示事件是否被处理。
RoutedEvent:实际的传递事件对象(比如Button.ClickEvent)。这个对于相同的处理函数处理多个传递事件时非常有用,可以用来区别传递事件。
Source和OriginalSource代表了逻辑树和视觉树对象。这有利于我们进行一些低级控制,但是对于有的事件,不需要区别它们,这两个的值是相同的。
现在,我们看看WPF到底是如何处理Bubbling和Tunneling事件的。最后介绍了Attached事件。
在UIElement类,预定义了很多的传递事件,比如键盘、鼠标等等。其中大多数是Bubbling事件,其中很多的事件都还有一个对应的Tunneling事件。所有的Tunneling事件都是Preview前缀命名,它们都在对应的Bubbling事件之前激发。比如PreviewMouseMove这个Tunneling事件是在MouseMove这个Bubbling事件之前激发的。
Tunneling事件的好处就是可以有机会改变或者取消后面的Bubbling事件。WPF内建的响应事件只会对Bubbling事件进行响应,当然,前提了Bubbling和Tunneling同时定义。这种行为有什么好处呢?
看下面的一个WPF事件策略例子:比如,我们想实现一种特殊的编辑框,只允许输入一些特定的字符。以前的实现方法在处理编辑框的KeyDown或者编辑框的WM_CHAR事件,然后判断新输入的字符是否满足条件,如果不满足,我们再把编辑框的值设置为原来的值。这种实现技术会有字符的一个回退过程。而在WPF中,实现方法不同,直接在PrevewKeyDown等Tunneling事件中处理,如果是不需要的字符,把事件设置为已经处理过。
这样这个事件就不会进入到后面的Bubbling事件KeyDown中,WPF也根本不会显式这个字符。这种方法的效果将比之前的回退处理好很多。
虽然我们可以通过RoutedEventArgs参数的Handled属性为True来终止事件的传递。但是,有时候我们需要某个事件始终被接受处理,这可以通过程序代码实现。使用重载的AddHanlder方法。比如,我们给窗口添加一个鼠标右键的处理方法(其中MRBD_Handler是类的一个事件方法):
- public AboutDialog() {
- InitializeComponent();
- this.AddHandler(Window.
MouseRightButtonDownEvent,
new MouseButtonEventHandler
(MRBD_Handler), true);- }
这样,任何条件下,MRBD_Handler都可以接收到窗口的鼠标右键事件。即使鼠标右键是点击在窗口中的某个子控件之上。
以上就是对WPF事件策略的一些相关介绍。