WPF Unleashed Chapter 3:Important New Concepts in WPF ---Routed Events

  
Routed Events   
  
  
        WPF在简单.NET的属性上架添了许多基础构,同样地也将许多的基础构架添加到了.NET的事件中。Routed event触发时,它会沿着视觉树和虚拟树向上或向下传递。这种在每一个元素上进行传递的行为是一种简单,稳固的方式,可以省去额外用户代码。

        事件路由帮助应用程序隐藏了视觉树的细节(这对进行restyle有帮助),并且这也是WPF元素组合的成功所在。例如,Button暴露了Click事件,Click事件可以处理低级别的MouseLeftButtonDown事件和KeyDown事件。虽然用户是在Button控件上按下鼠标左键,但实际上进行交互的却是Button控件的视觉子元素:ButtonChrome或TextBlock。因为事件会沿着视觉树(事件通过ButtonChrome或TextBlock向上传递,译者注)向上传递,最终会传递到Button控件进行操作。还记得前面介绍的录音机的暂停按钮吗?用户可以直接在Button的逻辑子元素Rectangle上点击鼠标左键,其结果也是一样的。因为事件会传递到逻辑树,最终Button仍然会接受到并对其进行处理。

        基于以上原因,您可以将任何复杂的内容嵌入到类似Button这种元素中去,或者将它组合成一个复杂的视觉树(第十章介绍),并且对这些内部元素进行鼠标左键点击操作也触发Button的Click事件。如果没有Routed Event,创建内部元素或者使用Button的人就要自己去编写代码来完成上面的过程了。  
  
        Routed Event的实现和行为和DP有很多共同之处。和介绍DP一样,我们首先看一下Routed Event是如何实现的,然后再结合About dialgo的实例对它的几个特性进行讨论。

  

A Routed Event Implementation

        大多数情况下,Routed Event和.NET的正常事件没什么区别。和DP一样,任何NET语言(除了XAML)可以理解Routed Event。他也是由大量的WPF的API构建的。List3.6演示了Button控件如何有效地实现Click的Routed Event。(实际上Click的Routed Event是由Button的基类实现的,但这并不是讨论的重点)。

        Routed Event和DP有很多相似之处。它也是公共的(public),静态的(static)成员,并按照惯例以“Event”字符串结尾。Routed Event注册也在静态构造函数完成的。为Routed Event添加了事件包装器(event wrapper)后就可以像常规的.NET事件那样使用了,并可以在XAML中使用。在Routed Event的包装器中不能添加除了AddHandler和RemoveHandler之外的代码。

  
      LISTING 3.6 A Standard Routed Event Implementation


      public class Button : ButtonBase
      {
            // The routed event
            public static readonly RoutedEvent ClickEvent;
            static Button()
            {
                  // Register the event
                  Button.ClickEvent = EventManager.RegisterRoutedEvent(“Click”,
                  RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(Button));
                  …
            }
            // A .NET event wrapper (optional)
            public event RoutedEventHandler Click
            {
                  add { AddHandler(Button.ClickEvent, value); }
                  remove { RemoveHandler(Button.ClickEvent, value); }
            }
            protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
            {
                  …
                  // Raise the event
                  RaiseEvent(new RoutedEventArgs(Button.ClickEvent, this));
                  …
            }
            …
      }
     

 


        AddHandler和RemoveHandler方法并不是定义在DependencyObject类中,而是定义在比其更高级的System.Windows.UIElement。这两个方法可以将委托添加到Routed Event,或从中移除。OnMouseLeftButtonDown方法内的RaiseEvent(也是定义在UIElement类中)会被相应的RoutedEvent调用,然后触发Click事件。Button的实例作为事件的源元素(source element)传递给Click事件。虽然没有在列表中列出,但是当用户敲击空格键或者回车键时会触发KeyDown事件,Click事件也会进行响应。
 
     下一篇介绍Routed Event的路由策略和事件处理(Routing Strategies and Event Handlers)。如果您有WPF方面的问题,可以给我留言一起探讨,感谢大家浏览
posted on 2007-07-05 11:22  stswordman  阅读(3397)  评论(3编辑  收藏  举报