深入浅出路由事件

为了降低由事件订阅带来的耦合度和代码量,WPF推出了路由事件机制。路由事件与直接事件的区别在于,直接事件激发时,发送者直接将消息通过事件订阅交送给事件响应者,事件响应者使用其事件处理器方法对事件的发生做出响应,驱动程序逻辑按客户需求运行;路由事件的事件拥有者和事件响应者之间则没有直接显示的订阅关系,事件的拥有者只负责激发事件,事件将由谁响应它并不知道,事件的响应者则安装有事件侦听器,针对某类事件进行侦听,当有此类事件传递至此时事件响应者就使用事件处理器来响应事件并决定事件是否可以继续传递。

顺便说一句,尽管WPF推出了路由事件机制,但它仍然支持传统的直接事件模型。

使用WPF内置路由事件

我用Button的CLick事件来说明路由事件的使用。请看下面例子。

XAML代码如下:

<Window x:Class="WpfApplication12.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Routed" Width="200" Height="200">
<Grid x:Name="gridRoot" Margin="10" Background="Lime">
<Grid x:Name="gridA" Margin="10" Background="Blue">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Canvas x:Name="canvasLeft" Grid.Column="0" Background="Red" Margin="10">
<Button x:Name="buttonLeft" Content="Left" Width="40" Height="100" Margin="10" Canvas.Left="-7" Canvas.Top="-10" />
</Canvas>
<Canvas x:Name="canvasRight" Grid.Column="1" Background="Yellow" Margin="10">
<Button x:Name="buttonRight" Content="Right" Width="40" Height="100" Margin="10" Canvas.Left="-7" Canvas.Top="-10" />
</Canvas>
</Grid>
</Grid>
</Window>
其运行效果如下:

深入浅出路由事件

Logical Tree结构图如图所示:

深入浅出路由事件

当单击buttonLeft时,Button.Click事件就会沿着buttonLeft->canvasLeft->gridA->gridRoot->Window这条线向上传递,单击buttonRight,则Button.Click事件沿着buttonRight->canvasRight->gridA->gridRoot->Window路线传送。因为目前还没有那个控件侦听Button.Click事件。所以单击按钮后尽管事件向上传递并没有受响应。下面为gridRoot安装针对Button.Click事件的侦听器。

方法很简单,就是字窗体的构造器中调用gridRoot的AddHandler方法把想监听的事件与事件的处理器关联起来。

public MainWindow()
{
InitializeComponent();
this.gridRoot.AddHandler(Button.ClickEvent,new RoutedEventHandler(this.ButtonClicked));
}

private void ButtonClicked(object sender,RoutedEventArgs e)
{
MessageBox.Show((e.OriginalSource as FrameworkElement).Name);
}

运行效果如下:

深入浅出路由事件 深入浅出路由事件

posted @ 2016-09-29 21:33  天涯海角路  阅读(201)  评论(0)    收藏  举报