第5章 路由事件(1)——概述
来源:互联网 发布:松下网络摄像机软件 编辑:程序博客网 时间:2024/06/18 16:45
一、概述
属性和事件是.NET抽象模型的核心部分,是每位.NET编程人员都十分熟悉的主题,但是WPF将属性和事件都进行了升级。WPF创建了一个新的依赖属性系统,重写了传统的.NET属性以提高性能并集成新功能(例如数据绑定和动画)。同时使用更高级的路由事件功能替换普通的.NET事件,使事件可在元素树中向上冒泡和向下隧道传播,并沿着传播路径被事件处理程序处理。
二、路由事件有三种形式
1、直接路由事件
直接路由事件与普通.NET事件类似,他们源于一个元素,不传递给其他元素。例如,MouseEnter事件(当鼠标指针移到元素上时发生)是直接路由事件。
2、冒泡路由事件
在包含层次中向上传递。该事件首先由被单击的元素引发,接下来被该元素的父元素引发,然后被父元素的父元素引发,依次类推,直到WPF到达元素树的顶部为止。例如,MouseDown事件就是冒泡路由事件。
3、隧道路由事件
在包含层次中向下传递。隧道路由事件在事件到达恰当的控件之前为预览事件(甚至终止事件)提供了机会。例如,通过PreviewKeyDown事件可截获是否按下某个键。首先在窗口级别上,然后是更具体的容器,直到到达当按下键时具有焦点的元素。
三、路由事件的便利性
WPF中的许多控件都是内容控件,而内容控件可包含任何类型以及大量的嵌套内容。例如,有一个文本标签,其中包含一个StackPanel面板,该面板又包含两个文本和一个图像,具体XAML代码如下:
<Window x:Class="WpfApplication5_1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApplication5_1" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525"> <StackPanel> <Label BorderBrush="Black" BorderThickness="1"> <StackPanel> <TextBlock Margin="3">Image and picture label</TextBlock> <Image Source="happyface.jpg" Stretch="None"></Image> <TextBlock Margin="3">Courtesy of the StackPanel</TextBlock> </StackPanel> </Label> </StackPanel></Window>效果图如下:
放在WPF窗口中的所有元素都在一定层次上继承自UIElement类,包括Label、StackPanel、TextBlock和Image等。UIElement定义了一些核心事件。例如,每个继承自UIElement的类都提供MouseDown事件和MouseUp事件。
元素和控件基类框图如下:
如果现在有这样一个需求,要求单击Lable标签来触发同一个事件处理程序,显然可以为Lable标签内的每个元素的MouseDown或MouseUp事件关联同一个事件处理程序,但这样会使标记变得杂乱无章且难以维护。
注意:此处为什么使用MouseDown或MouseUp事件而不使用Click事件,这是因为大多数WPF元素没有提供Click事件,而是提供了更直接的MouseDown或MouseUp事件。Click事件专用于继承自ButtonBase的控件。
MouseDown或MouseUp事件都是冒泡路由事件,此时可在标签级别或更高级别处理MouseDown或MouseUp事件,就可以实现无论单击标签内的哪个元素都可以触发同一个事件处理程序,而代码仅需要一行。具体代码如下:
XAML标记代码:
<Window x:Class="WpfApplication5_1.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:WpfApplication5_1" mc:Ignorable="d" Title="MainWindow" Height="350" Width="525"> <StackPanel> <Label BorderBrush="Black" BorderThickness="1" MouseDown="lbl_Event"> <StackPanel> <TextBlock Margin="3">Image and picture label</TextBlock> <Image Source="happyface.jpg" Stretch="None"></Image> <TextBlock Margin="3">Courtesy of the StackPanel</TextBlock> </StackPanel> </Label> </StackPanel></Window>
VS后台代码:
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Windows;using System.Windows.Controls;using System.Windows.Data;using System.Windows.Documents;using System.Windows.Input;using System.Windows.Media;using System.Windows.Media.Imaging;using System.Windows.Navigation;using System.Windows.Shapes;namespace WpfApplication5_1{ /// <summary> /// MainWindow.xaml 的交互逻辑 /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void lbl_Event(object sender, MouseButtonEventArgs e) { MessageBox.Show("触发源:" + e.Source); //e.Source指示引发了事件的对象 } }}
四、路由事件的两个参数
所有WPF事件都为事件签名使用熟悉的.NET约定。每个事件处理程序都有两个参数,具体如下:
1、第一个参数:sender指事件触发时调用该事件的对象。例如,上例中指的是Label对象。
2、第二个参数:RoutedEventArgs或其派生类。
如果用同一个事件处理程序处理不同的事件,这一信息非常有用Handled该属性允许终止事件的冒泡或隧道过程。
如果控件将Handled属性设为true,那么事件就不会继续传递,也不会再为其他任何元素引发该事件在WPF中,如果事件不需要传递任何额外细节,可使用RoutedEventArgs类,该类包含了有关如何传递事件的一些细节。如果事件确实需要传递额外的信息,那么需要使用更特殊的继承自RoutedEventArgs的对象。因为每个WPF事件参数类都继承自RoutedEventArgs类,所以每个WPF事件处理程序都可访问与事件路由有关的信息。
五、代码下载
WpfApplication5_1.rar提取码:xu8v
- 第5章 路由事件(1)——概述
- 第5章 路由事件(5)——自定义路由事件
- 第5章 路由事件(2)——冒泡路由事件
- 第5章 路由事件(3)——隧道路由事件
- 第5章 路由事件(4)——附加路由事件
- 事件和路由事件概述
- 路由事件——附加事件案例
- JavaScript权威指南_158_第17章_事件处理_17.1-事件类型-概述
- 第1章 概述
- 第1章 概述
- 第1章 概述
- 第1章 概述
- JavaScript程序设计——第1章 JavaScript概述
- 作业——第1章 软件体系结构概述
- 第4章 依赖属性(1)——概述
- 第18章 自定义元素(1)——概述
- 第9章 命令(1)——概述
- 第九章 路由协议概述
- SQL Server 表分区
- C语言移位操作遇到的问题和解决办法
- js获取cookie
- Struts2+spring3+mybatis3整合注解开发
- 版本控制svn-Versions
- 第5章 路由事件(1)——概述
- Delphi FireDAC 出现Variable length column[*] overflow. Value length - [80], column maximum length
- hdu3910 Liang Guo Sha(期望)
- android中利用sharedpreference进行数据存储
- Git分支管理策略
- win10 uwp InkCanvas控件数据绑定
- 硬解和软解的区别
- Java项目 1 - 学生成绩管理系统---采用 Servlet+Jsp+JavaBean+MySql 设计方式,
- leetCode练习(46)