WPF编程宝典之路由事件
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了WPF编程宝典之路由事件相关的知识,希望对你有一定的参考价值。
路由事件是更具有传播能力的事件——它们可在元素树中向上冒泡和向下隧道传播,并且沿着传播路径被事件处理程序处理。
可通过传统的方式使用路由事件——通过关联具有正确签名的事件处理程序。
1.定义、注册和封装路由事件
与依赖项属性一样,路由事件由只读的静态字段表示,在静态构造函数中注册,并通过标准的.net事件定义进行封装。
1 public abstract class ButtonBase : ContentControl
2 {
3 //定义事件
4 public static readonly RoutedEvent ClickEvent;
5 //注册事件
6 static ButtonBase()
7 {
8 ButtonBase.ClickEvent = EventManager.RegisterRutedEvent(
9 "Click",RoutingStrategy.Bubble,
10 typeof(RoutedEventHandler),typeof(ButtonBase));
11 }
12 }
路由事件使用EventManager.RegisterRoutedEvent()方法注册。
注册时需要指明:
- 事件的名称
- 路由类型
- 定义事件处理程序语法的委托
- 拥有事件的类。
通常,路由事件通过普通的.NET事件进行封装,从而使所有.net语言都能访问。事件封装器可使用AddHandler()和RemoveHandler()方法添加和删除已注册的调用程序,这两个方法在FrameworkElement基类中定义,并被每个WPF元素继承。
2.共享路由事件
1 UIElement.MouseUpEvent = Mouse.MouseUpEvent.AddOwner(typeof(UIElement));
UIElement(该类是所有普通WPF元素的起点)类通过Routed-Event.AddOwner()方法重用MouseUp事件。
3.引发路由事件
事件不通过传统的.NET事件封装器引发,而是使用RaiseEvent()方法引发,所有元素都从UIElement类继承了该方法
1 RoutedEventArgs e = new RoutedEventArgs(ButtonBase.ClickEvent, this);
2 base.RaiseEvent(e);
RaiseEvent()方法负责为每个已经通过AddHandler()方法注册的调用程序引发事件。
所有WPF事件都为事件签名使用熟悉的.NET约定,每个事件处理程序的第一个参数(sender参数)都提供引发该事件的对象的引用;第二个参数EventArgs对象,该对象与其他重要的附加细节绑定在一起。例如,MouseUp事件提供了一个MouseEventArgs对象,用于指示当事件发生时按下了哪些鼠标:
1 private void img_MouseUp(object sender, MouseButtonEventArgs e)
2 {
3
4 }
4.处理路由事件
最常用的方法是XAML标记添加事件特性:
1 <Image Source="happyface.jpg" Stretch="None"
2 Name="img" MouseUp="img_MouseUp" />
也可以通过代码连接事件:
1 img.MouseUp += new MouseButtonEventHandler(img_MouseUp);
2 //或者
3 //img.MouseUp += img_MouseUp;
5.路由事件出现的三种方式
- 与普通.net事件类似的直接路由事件。事件源于一个元素,不传递给其他元素,例如MouseEnter事件;
- 在包含层次中向上传递的冒泡路由事件(bubbling event)。例如MouseDown事件,首先由被单击的元素引发,接下来被元素的父元素引发,然后被父元素的父元素引发,直到元素树的顶部;
- 在包含层次中向下传递的隧道路由事件(tunneling event)。例如PreviewKeyDown事件,首先在窗口级别上,然后是更具体的容器,直至到达当按下键时具有焦点的元素。
6.RoutedEventArgs类
名称 | 说明 |
Source | 指示引发了事件的对象 |
OriginalSource | 指示最初是什么对象引发了事件 |
RoutedEvent | 通过事件处理程序为触发的事件提供RoutedEvent对象 |
Handled | 该属性允许终止事件的冒泡或隧道过程。如果控件将Handled属性设为true,那么事件就不会继续传递,也不会再为其他任何元素引发该事件。 |
7.附加事件
如果上一层的控件不支持下一层控件的事件,而需要将下一层的若干控件添加相同的事件处理方法,需要用到“附加事件”
1 <StackPanel Button.Click="DoSomething" Margin="5">
2 <Button Name="cmd1">Command 1</Button>
3 <Button Name="cmd2">Command 1</Button>
4 <Button Name="cmd3">Command 1</Button>
5 <StackPanel>
这样所有的Button的单击事件都可以被捕获。
8.生命周期事件
(1)所有元素的生命周期事件
名称 | 说明 |
Initialized | 当元素被实例化,并以已根据XAML标记设置了元素的属性之后发生 |
Loaded | 当整个窗口已经初始化并应用了样式和数据绑定,该事件发生。 |
Unloaded | 当元素被释放时,该事件发生。 |
(2)Window类的生命周期事件
- SourceInitialized
- ContentRendered
- Activated
- Deactivated
- Closing
- Closed
(3)键盘事件
- PreviewKeyDown
- KeyDown
- PreviewTextInput
- TextInput
- PreviewKeyUp
- KeyUp
(4)获取键盘状态
- IsKeyDown
- IsKeyUp
- IsKeyToggled
- GetKeyStates
(5)鼠标单击
- PreviewMouseLeftButtonDown
- MouseLeftButtonDown
- PreviewMouseLeftButtonUp
- MouseLeftButtonUp
以上是关于WPF编程宝典之路由事件的主要内容,如果未能解决你的问题,请参考以下文章