在WPF中,例如,可以构建一个包含图形的按钮,创建一个具有文本和图片混合内容的标签,或者为了实现滚动或折叠的显示效果在一个特定的容器中放置内容。甚至可以多此重复嵌套,直到达到您所希望的层次深度。

这种可以任意嵌套的能力也带来了一个有趣的问题。例如,假设有一个标签,它包含一个StackPanel面板,该面板又包含了两块文本图像:

<Label BorderBrush="Black" BorderThickness="1">
<StackPanel>
<TextBlock Margin="3">Image and text label</TextBlock>
<Image Source="c:\1.jpg" Stretch="None" />
<TextBlock Margin="3">Courtesy of the StackPanel</TextBlock>
</TextBlock>
</StackPanel>
</Label>

正如您已经知道的,放在WPF窗口中的所有要素都在一定层次上继承自UIElement类,包括Label、StackPanel、TextBlock 和 Image 。 UIElement 定义了一些核心事件。例如,每个继承自 UIElement 的类都具有一个 MouseDown 事件和 MouseUp 事件。

但是当单击上面这个特殊标签中的图像部分时,想一想会发生什么事情?很明显,印发Image.MouseDown 事件和 Image.MouseUp 事件是合情合理的。但是我们一般实际期望的结果并不是这样,而是无论用户单击了图像、某块文本还是标签内的空白处。不管在什么位置点击都触发同一个事件来进行处理。

因为MouseUp事件和MouseDown事件都是冒泡路由事件,所以他们会依次向上传递事件触发,如:点击TextBlock 会依次触发:TextBlock、StackPanel、Lable、.....直到window窗体为最后一站传递点。也许这也并不是我们希望的结果,幸运的是在 WPF 中所有事件的参数类都继承自 RoutedEventArgs ,任何事件处理程序都可以使用这些属性。其中有一个 Handled 属性,则是可以终止继续往上层次冒泡的属性。该属性为True时,则终止冒泡。

下面以一个例子来实验这种冒泡路由事件效果:

效果:

XAML代码:

<Window x:Class="_1015_BubbledEvent.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid Margin="3">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions> <Label Margin="5" Grid.Row="0" HorizontalAlignment="Left" Background="AliceBlue" BorderBrush="Black" BorderThickness="1" MouseUp="SomethingClicked">
<StackPanel MouseUp="SomethingClicked">
<TextBlock Margin="3" MouseUp="SomethingClicked">Image and text label</TextBlock>
<Image Source="c:\1.jpg" Stretch="Fill" Width="100" Height="100" MouseUp="SomethingClicked"/>
<TextBlock Margin="3" MouseUp="SomethingClicked">Courtesy of the StackPanel</TextBlock>
</StackPanel>
</Label>
<ListBox Grid.Row="1" Margin="5" Name="lstMessage"/>
<CheckBox Grid.Row="2" Margin="5" Name="chkHandle">Handle first event</CheckBox>
<Button Grid.Row="3" Margin="5" Padding="3" HorizontalAlignment="Right" Name="cmdClear" Click="cmdClear_Click_1">Clear List</Button>
</Grid>
</Window>

注意:代码中包含了在C:\1jpg 文件,请自行随意找一个文件代替吧。

C#代码:

        int _eventCounter = ;
private void SomethingClicked(object sender, MouseButtonEventArgs e)
{
_eventCounter++;
string message = "#" + _eventCounter.ToString() + ":\r\n" +
" Sender: " + sender.ToString() + "\r\n" +
" Source: " + e.Source + "\r\n" +
" Original Source: " + e.OriginalSource;
lstMessage.Items.Add(message);
e.Handled = (bool)chkHandle.IsChecked;
} private void cmdClear_Click_1(object sender, RoutedEventArgs e)
{
_eventCounter = ;
lstMessage.Items.Clear();
}

源码下载:http://files.cnblogs.com/andrew-blog/1015_BubbledEvent.rar

使用工具:VS2012

参考:http://www.wxzzz.com/?id=128

WPF 冒泡路由事件的更多相关文章

  1. WPF教程六:理解WPF中的隧道路由和冒泡路由事件

    WPF中使用路由事件升级了传统应用开发中的事件,在WPF中使用路由事件能更好的处理事件相关的逻辑,我们从这篇开始整理事件的用法和什么是直接路由,什么是冒泡路由,以及什么是隧道路由. 事件最基本的用法 ...

  2. 学习WPF——了解路由事件

    入门 我们先来看一个例子 前台代码: 后台代码: 点击按钮的运行效果第一个弹出窗口 第二个弹出窗口: 第三个弹出窗口: 说明 当点击按钮之后,先触发按钮的click事件,再上查找,发现stackpan ...

  3. 迟到的 WPF 学习 —— 路由事件

    1. 理解路由事件:WPF 通过事件路由(event routing)概念增强了传统的事件执行的能力和范围,允许源自某个元素的事件由另一个元素引发,例如,事件路由允许工具栏上的一个按钮点击的事件在被代 ...

  4. WPF 隧道路由事件

    阅读本文前,请先了解 冒泡路由事件:http://www.cnblogs.com/andrew-blog/p/WPF_BubbledEvent.html 隧道路由事件的工作方式和冒泡路由事件相同,但方 ...

  5. WPF - 善用路由事件

    原文:WPF - 善用路由事件 在原来的公司中,编写自定义控件是常常遇到的任务.但这些控件常常拥有一个不怎么好的特点:无论是内部还是外部都没有使用路由事件.那我们应该怎样宰自定义控件开发中使用路由事件 ...

  6. WPF的路由事件、冒泡事件、隧道事件(预览事件)

    本文摘要: 1:什么是路由事件: 2:中断事件路由: 3:自定义路由事件: 4:为什么需要自定义路由事件: 5:什么是冒泡事件和预览事件(隧道事件): 1:什么是路由事件 WPF中的事件为路由事件,所 ...

  7. 【WPF】路由事件

    总结WPF中的路由事件,我将学到的内容分为四部分来逐渐掌握 第一部分:wpf中内置的路由事件 以Button的Click事件来说明内置路由事件的使用 XAML代码: <Window x:Clas ...

  8. WPF中路由事件的传播

    路由事件(RoutedEvent)是WPF中新增的事件,使用起来与传统的事件差别不大, 但传播方式是完全不同的. 路由事件的传播方式 通过RoutingStrategy来定义传播的方式 public ...

  9. 细说WPF自定义路由事件

    WPF中的路由事件 as U know,和以前Windows消息事件区别不再多讲,这篇博文中,将首先回顾下WPF内置的路由事件的用法,然后在此基础上自定义一个路由事件. 1.WPF内置路由事件   W ...

随机推荐

  1. 掀开图片显示介绍的css效果

    概述 主要运用到CSS3的3D transform等变换 详细 代码下载:http://www.demodashi.com/demo/10575.html 一.概述 1.主要运用到CSS3的3D tr ...

  2. 工具-VIM配置

    设置缩进的空格数 shiftwidth=4 设置制表符宽度 tabstop=4 高亮显示当前行 cursorline 高亮显示当前列 cursorcolumn

  3. Web Service-WSDL详解

    WSDL指网络服务描述语言 (Web Services Description Language), 是一种用XML编写的文档, 用于描述Web Service和函数.参数以及返回值等; 文档内规定了 ...

  4. Matlab调用返回游标的存储过程的分析和处理

    2.Matlab调用Oracl带游标参数输出的存储过程 笔者也是将工作之中遇到的问题进行了搜集与整理,才完成该文的编写,希望能帮助到有需要的朋友. 2.1.PLSQL中的存储过程 PROCEDURE ...

  5. ACM遇到的问题与解决方案

    C++防止栈溢出措施: 只要在你的代码里加上下面这句话, OK,栈溢出直接搞定!!! #pragma comment(linker, "/STACK:102400000,102400000& ...

  6. 最全Android开发常用工具类

    主要介绍总结的Android开发中常用的工具类,大部分同样适用于Java. 目前包括  HttpUtils.DownloadManagerPro.Safe.ijiami.ShellUtils.Pack ...

  7. 如何在win7下安装和配置Android Studio

    下载地址:http://developer.android.com/sdk/installing/studio.html#download 如果出现启动不了的问题 进入Android Studio安装 ...

  8. 在 Asp.NET MVC 中使用 SignalR 实现推送功能 [转]

    在 Asp.NET MVC 中使用 SignalR 实现推送功能 罗朝辉 ( http://blog.csdn.net/kesalin ) CC许可,转载请注明出处 一,简介 Signal 是微软支持 ...

  9. 【js】typeof与instanceof

    typeof 运算符 返回一个用来表示表达式的数据类型的字符串. typeof[()expression[]] ; expression 参数是需要查找类型信息的任意表达式. 说明 typeof 运算 ...

  10. JMeter学习笔记--JMeter常用测试元件

    JMeter测试计划有一个被称为“函数测试模式”的选项,如果被选择,它会使Jmeter记录来自服务器返回的每个取样的数据.如果你在测试监听器中选择一个文件,这个数据将被写入文件.如果你尝试一个较小的测 ...