什么是路由?
路由(routing)是指分组从源到目的地时,决定端到端路径的网络范围的进程 。
什么是路由事件
功能定义:路由事件是一种可以针对元素树中的多个侦听器(而不是仅针对引发该事件的对象)调用处理程序的事件。
实现定义:路由事件是一个CLR事件,可以由RoutedEvent类的实例提供支持并由Windows Presentation Foundation(WPF)事件系统来处理。
典型的WPF应用程序中包含许多元素。无论这些元素是在代码中创建的还是在XAML中声明的,它们都是由共同所在的元素树关联起来。根据事件的定义,事件路由可以按两种方向之一传播,但是通常会在元素树中从源元素向上“冒泡”,直到它到达元素树的根(通常是页面或窗口)。
请考虑下面的简单元素树
<Border Height="50" Width="300" BorderBrush="Gray" BorderThickness="1">
<StackPanel Background="LightGray"
Orientation="Horizontal"
Button.Click="CommonClickHandler">
<Button Name="YesButton" Width="Auto">Yes</Button>
<Button Name="NoButton" Width="Auto">No</Button>
<Button Name="CancelButton" Width="Auto">Cancel</Button>
<StackPanel>
</Border>
在这个简单的元素树中,Click事件的源是某个Button的元素,而所单击的Button事件是有机会处理该事件的第一个元素。但是,如果附加到Button的任何处理程序均未作用于该事件,则该事件将向上“冒泡”到元素树中的Button父级(即StackPanel)。该事件可能会“冒泡”到Border,然后会到达元素树的页面根(未显示出来)。
换言之,此Click事件的事件路由为:
Button-->StackPanel-->Border-->...
路由事件的顶级方案
控件的撰写和封装:WPF中的各个控件都有一个丰富的内容模型。例如,可以将图像放在Button的内部,这会有效地扩展按钮的可视化树。但是,所添加的图像不得中断命中测试行为(该行为会使按钮响应对图像内容的Click),即使用户所单击的像素在技术上shu'yu该图像也是如此。
单一处理程序附加点:在Windows窗体中,必须多次附加同一个处理程序,才能处理可能是从多个元素引发的事件。路由事件使您可以只附加该处理程序一次(像上例中那样),并在必要时使用处理程序逻辑来确定该事件源自何处。例如,这可以是前面显示的XAML的处理程序:
private void CommonClickHander(object sender, RoutedEventArgs e)
{
FrameworkElement feSource = e.Source as FrameworkElement;
switch(feSource.Name)
{
case "YesButton":
//doing something here...
break;
case "NoButton":
//doing something here...
break;
case "CancelButton":
//doing something here...
break;
Default:
//doing something here...
break;
}
e.Handled = true;
}
类处理:路有事件允许使用由类定义的静态处理程序。这个类护理程序能够抢在任何附加的实例处理程序之前来处理事件。
引用事件,而不反射:某些代码和标记技术需要能标识特定事件的方法。路有事件创建RoutedEvent字段作为标识符,以此提供不需要静态反射或运行时反射的可靠的事件标识技术。
路由事件的实现方式
路由事件时一个CLR事件,它由RoutedEvent类提供支持并用WPF事件系统注册。从注册中获取的RoutedEvent实例通常保留为某种类的public static readonly字段成员,该类进行了注册并因此拥有路由事件。与同名CLR事件(又称包装事件)的连接是通过重写CLR事件的add和remove实现来完成的。通常,add和remove保留为隐式默认值,该默认值使用特定于语言的相应事件语法来添加和移除该事件的处理程序。路由事件的支持和连接机制在概念上与以下机制相似:依赖项属性是一个CLR属性,该属性由DependencyProperty类提供支持并用WPF属性系统注册。
下面的实例演示自定义Tap路由事件的声明,其中包括注册和公开RoutedEvent标识符字段以及对Tap CLR事件进行add和remove的实现。
public static readonly RoutedEvent TapEvent = EventManager.RegisterRoutedEvent{
"Tap", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MyButtonSample)};
//Provide CLR accessors for the event
public event RoutedEventHandler Tap
{
add{ AddHandler(TapEvent, value);}
remove{ RemoveHandler(TapEvent, value);}
}
Public Shared ReadOnly TapEvent As RoutedEvent = EventManager.RegisterRoutedEvent{ "Tap",
RoutingStrategy.Bubble, GetType(RoutedEventHandler), GetType(MyButtonSample)}
'Provide CLR accessors for the event
Public Custom Event Tap As RoutedEventHandler
AddHandler(ByVal value As RoutedEventHandler)
Me.AddHandler(TapEvent, value)
End AddHandler
RemoveHandler(ByVal value As RoutedEventHandler)
Me.RemoveHandler(TapEvent, value)
End RemoveHandler
RaiseEvent(ByVal sender As Object, ByVal e As RoutedEventArgs)
Me.RaiseEvent(e)
End RaiseEvent
End Event
(PS:学着WPF,突然就来一段VB的东西,一脸懵逼)
下一节接着学习:路由事件处理程序和XAML