一、事件路由

1. 直接路由事件

  起源于一个元素,并且不能传递给其他元素

MouserEnter 和MouserLeave 就是直接事件路由

2. 冒泡路由事件

  在包含层次中向上传递,首先由引发的元素触发,然后被父元素引发,直到到达WPF的元素树的顶部位置

例如:MouserUp

以下控件都绑定了,MouseUp事件。根据输出的顺序表现冒泡路由的效果

<Window x:Class="Haos.WPF.Case.Event.BubbleRouteWindow"
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:Haos.WPF.Case.Event"
mc:Ignorable="d"
Title="BubbleRouteWindow" Height="300" Width="300">
<!--冒泡路由-->
<Grid Margin="3" MouseUp="SomethingClick">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Label Margin="5" Background="AliceBlue" BorderBrush="Black" BorderThickness="1" HorizontalAlignment="Center" Grid.Row="0" MouseUp="SomethingClick">
<StackPanel MouseUp="SomethingClick">
<TextBlock Margin="3" TextAlignment="Center" MouseUp="SomethingClick">Image and Picture Lable</TextBlock>
<Image Source="/Images/logo_ye.png" Width="20" Stretch="Fill" MouseUp="SomethingClick"></Image>
<TextBlock Margin="3" TextAlignment="Center" MouseUp="SomethingClick">Courtesy of the StackPanel</TextBlock>
</StackPanel>
</Label>
<ListBox Margin="5" Name="lstMessage" Grid.Row="1"></ListBox>
<CheckBox Margin="5" Grid.Row="2" Name="Check_Box">Handle first event</CheckBox>
<Button Grid.Row="3" Margin="5" Padding="2" Click="Btn_Click">Clear List</Button>
</Grid>
</Window>
namespace Haos.WPF.Case.Event
{
/// <summary>
/// BubbleRouteWindow.xaml 的交互逻辑
/// </summary>
public partial class BubbleRouteWindow : Window
{
public BubbleRouteWindow()
{
InitializeComponent();
} public int EventCounter = ; /// <summary>
/// MouseUp 的处理程序
/// </summary>
/// <param name="sender">触发者</param>
/// <param name="e">事件参数</param>
private void SomethingClick(object sender, MouseButtonEventArgs e)
{
EventCounter++;
string message = $"#{EventCounter}:\r\nSender:{sender.ToString()}\r\nSource:{e.Source}\r\nOriginal Source:{e.OriginalSource}";
lstMessage.Items.Add(message);
e.Handled = (bool)Check_Box.IsChecked;
} private void Btn_Click(object sender, RoutedEventArgs e)
{
EventCounter = ;
lstMessage.Items.Clear();
}
}
}

3. 隧道路由事件

  在包含层次中向下传递,首先由WPF的元素树的顶部触发,然后向子元素引发,直到到达最后一个子元素

隧道路由的事件名称以Preview开头,例如PreviewKeyDown键盘按下事件

<Window x:Class="Haos.WPF.Case.Event.ChunnelRouteWindow"
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:Haos.WPF.Case.Event"
mc:Ignorable="d"
Title="ChunnelRouteWindow" Height="300" Width="300" PreviewKeyDown="SomethingKeyUp">
<!--隧道路由事件-->
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" PreviewKeyDown="SomethingKeyUp">
<TextBlock Margin="3" HorizontalAlignment="Center" PreviewKeyDown="SomethingKeyUp">Image and text Lable</TextBlock>
<Image Source="/Images/logo_ye.png" Width="20" Stretch="Fill" PreviewKeyDown="SomethingKeyUp"></Image>
<DockPanel PreviewKeyDown="SomethingKeyUp">
<TextBlock PreviewKeyDown="SomethingKeyUp">Type here:</TextBlock>
<TextBox PreviewKeyDown="SomethingKeyUp"></TextBox>
</DockPanel>
</StackPanel>
<ListBox Margin="5" Name="lstMessage" Grid.Row="1"></ListBox>
<CheckBox Margin="5" Grid.Row="2" Name="Check_Box">Handle first event</CheckBox>
<Button Grid.Row="3" Margin="5" Padding="2" Click="Btn_Click">Clear List</Button>
</Grid>
</Window>

二、事件类型

1. 生命周期事件

  1.1 Window.Initialized:在所有子元素都被设置完成时触发

    这个元素已经被构建出来,并且它的属性值都被设置好了,所以通常都是子元素先于父元素触发这个事件.当一个元素的 Initialized 事件被触发, 通常它的子树都已经初始化完成, 但是父元素还未初始化. 这个事件通常是在子树的 Xaml 被加载进来后触发的. 这个事件与 IsInitialized 属性相互绑定

  1.2 Window.Activated和Window.Deactivated:在窗口成为前台窗口时发生(激活)/在窗口成为后台窗口时发生

       户在运行系统上的多个窗口中切换时,Activated和Deactivated在窗口的生命周期里会发生多次

  1.3 Window.Loaded:在元素布局,呈现和准备交互时发生

    为了让一些事情能在所有内容都显示给用户之前马上执行,可以用Loaded事件

  1.4 Window.ContentRendered:在窗口的内容被渲染后发生

    ContentRendered事件只对窗口第一次完全呈现出来进行触发。为了让一些事情能在所有内容都显示给用户之后马上执行,可以用ContentRendered事件

  1.5 Window.Closed:当窗口即将关闭时发生  

  1.6 Window.Closing:Closed之后立即发生 Close 被调用,并且可以处理以取消关闭窗口。

2.鼠标事件

2.1 捕获鼠标坐标

捕获鼠标相对,元素的位置

2.2 捕获鼠标

当元素捕获鼠标以后,其他元素就无法触发其他元素上的,鼠标按钮类事件。直到 Mouse.Capture(null);方法接受到一个null参数。

2.3 鼠标拖放输入

用户单击或选择元素上一块区域,拖放动作开始,将鼠标移动到其他的元素上并且该元素可以接受拖放信息。

文本框自带拖放功能。

首先设置鼠标按下事件时,绑定拖放的源。在放目标元素开启,允许放属性AllowDrop。同时绑定Drop事件处理放的操作

<Window x:Class="Haos.WPF.Case.Event.MouseEventWindow"
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:Haos.WPF.Case.Event"
mc:Ignorable="d"
Title="MouseEventWindow" Height="300" Width="300">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<!--获取鼠标位置-->
<Rectangle Name="rect" Fill="AliceBlue" MouseMove="Rect_Move"></Rectangle>
<!--捕获鼠标-->
<Button Grid.Row="1" Name="Btn_Capture" Click="Capture_Click">Capture the Mouse</Button>
<TextBlock Grid.Row="2" Name="Txt_Block">Mouse posstion at (0,0) in window coordinates</TextBlock>
<DockPanel Grid.Row="3">
<!--设置拖动的源-->
<Label Background="DarkKhaki" Name="Txt_Scouce" MouseDown="Scouce_Down">this is label mouse</Label>
<!--被放的对象,开启允许拖放接受数据 AllowDrop="True"-->
<Label Background="Aqua" AllowDrop="True" Name="Lbl_Drop" Drop="Lbl_Drops"></Label>
</DockPanel>
</Grid>
</Window>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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.Shapes; namespace Haos.WPF.Case.Event
{
/// <summary>
/// MouseEventWindow.xaml 的交互逻辑
/// </summary>
public partial class MouseEventWindow : Window
{
public MouseEventWindow()
{
InitializeComponent();
}
/// <summary>
/// 鼠标在矩形移动
/// </summary>
/// <param name="sender"></param>
/// <param name="e">MouseEventArgs 不具备鼠标按钮,鼠标滚轮的事件提供的参数</param>
private void Rect_Move(object sender, MouseEventArgs e)
{
//获取鼠标坐标
Point point = e.GetPosition(this);
Txt_Block.Text = $"Mouse posstion at ({point.X},{point.Y}) in window coordinates";
if (point.X == )
{
//让被捕获的鼠标释放
Mouse.Capture(null);
}
} private void Capture_Click(object sender, RoutedEventArgs e)
{
Mouse.Capture(rect);
Btn_Capture.Content = "鼠标被捕获…";
} /// <summary>
/// 鼠标按下设置,拖放的源
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Scouce_Down(object sender, MouseButtonEventArgs e)
{
Label lbl = sender as Label; ;
//启动拖动
DragDrop.DoDragDrop(lbl, lbl.Content, DragDropEffects.Copy);
}
/// <summary>
/// 拖放,放的事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Lbl_Drops(object sender, DragEventArgs e)
{
Label lbl = sender as Label;
lbl.Content = e.Data.GetData(DataFormats.Text);
}
}
}

3.键盘事件

  按照执行顺序排列如下

  3.1 PreviewKeyDown:隧道键盘按下

  3.2 KeyDown:冒泡键盘按下

  3.3 PreviewTextInput:文本正在输入事件

  3.4 TextChanged:本文框值发生改变

  3.5 PreviewKeyUp:隧道键盘弹起

  3.6 KeyUp:冒泡键盘弹起

<Window x:Class="Haos.WPF.Case.Event.KeyboardEventWindow"
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:Haos.WPF.Case.Event"
mc:Ignorable="d"
Title="KeyboardEventWindow" Height="300" Width="300">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<DockPanel Margin="5" Grid.Row="0">
<TextBlock Margin="3">Type here:</TextBlock>
<TextBox Focusable="True" PreviewKeyDown="KeyEvent" KeyDown="KeyEvent" PreviewKeyUp="KeyEvent" KeyUp="KeyEvent" PreviewTextInput="TextBox_PreviewTextInput" TextChanged="TextBox_TextChanged"></TextBox>
</DockPanel>
<ListBox Margin="5" Grid.Row="1" Name="lstMessage"></ListBox>
<Button Grid.Row="2" Name="Btn_Clear" Padding="3" Margin="3" Click="Btn_Clear_Click">Clear ListBox</Button>
</Grid>
</Window>
namespace Haos.WPF.Case.Event
{
/// <summary>
/// KeyboardEventWindow.xaml 的交互逻辑
/// </summary>
public partial class KeyboardEventWindow : Window
{
public KeyboardEventWindow()
{
InitializeComponent();
} private void TextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
string message = $"Event:{e.RoutedEvent} Key:{e.Text}";
lstMessage.Items.Add(message);
} private void KeyEvent(object sender, KeyEventArgs e)
{
string message = $"Event:{e.RoutedEvent} Key:{e.Key}";
lstMessage.Items.Add(message);
} private void TextBox_TextChanged(object sender, TextChangedEventArgs e)
{
string message = $"Event:{e.RoutedEvent}";
lstMessage.Items.Add(message);
} private void Btn_Clear_Click(object sender, RoutedEventArgs e)
{
lstMessage.Items.Clear();
}
}
}

  3.7 焦点相关:

    Focusable设置控件是否能够获得焦点,和TabIndex属性设置按下Tab键获得焦点的顺序。在WPF中是使用树形结构布局的,所以当按下Tab键时,焦点会移动到当前元素的一个子元素。如果没有子元素,会移动到同级下一个元素的第一个子元素

4.手写笔事件

5.多点触控事件

WPF 入门笔记之事件的更多相关文章

  1. WPF 学习笔记 路由事件

    1. 可传递的消息: WPF的UI是由布局组建和控件构成的树形结构,当这棵树上的某个节点激发出某个事件时,程序员可以选择以传统的直接事件模式让响应者来响应之,也可以让这个事件在UI组件树沿着一定的方向 ...

  2. WPF 入门笔记之基础

    一.创建WPF程序 1. App.xaml 相当于窗体的配置文件 2. xmlns:xml名称空间的缩写 xmlns="http://schemas.microsoft.com/winfx/ ...

  3. WPF 入门笔记之控件内容控件

    一.控件类 在WPF中和用户交互的元素,或者说.能够接受焦点,并且接收键盘鼠标输入的元素所有的控件都继承于Control类. 1. 常用属性: 1.1 Foreground:前景画刷/前景色(文本颜色 ...

  4. WPF 入门笔记之布局

    一.布局原则: 1. 不应显示的设定元素的尺寸,反而元素可以改变它的尺寸,并适应它们的内容 2. 不应使用平布的坐标,指定元素的位置. 3. 布局容器和它的子元素是共享可以使用的空间 4. 可以嵌套的 ...

  5. 《深入浅出WPF》笔记——事件篇

    如果对事件一点都不了解或者是模棱两可的话,建议先去看张子阳的委托与事件的文章(比较长,或许看完了,也忘记看这一篇了,没事,我会原谅你的)http://www.cnblogs.com/JimmyZhan ...

  6. WPF入门:数据绑定

    上一篇我们将XAML大概做了个了解 ,这篇将继续学习WPF数据绑定的相关内容 数据源与控件的Binding Binding作为数据传送UI的通道,通过INotityPropertyChanged接口的 ...

  7. React.js入门笔记

    # React.js入门笔记 核心提示 这是本人学习react.js的第一篇入门笔记,估计也会是该系列涵盖内容最多的笔记,主要内容来自英文官方文档的快速上手部分和阮一峰博客教程.当然,还有我自己尝试的 ...

  8. WPF入门教程系列三——Application介绍(续)

    接上文WPF入门教程系列二——Application介绍,我们继续来学习Application 三.WPF应用程序的关闭 WPF应用程序的关闭只有在应用程序的 Shutdown 方法被调用时,应用程序 ...

  9. WPF入门教程系列(二) 深入剖析WPF Binding的使用方法

    WPF入门教程系列(二) 深入剖析WPF Binding的使用方法 同一个对象(特指System.Windows.DependencyObject的子类)的同一种属性(特指DependencyProp ...

随机推荐

  1. Delphi 10.2可以开发Linux桌面应用了

    原始地址 https://community.embarcadero.com/blogs/entry/firemonkey-on-linux    Delphi Linux编译器已经发布,现在无需等待 ...

  2. 获取bing图片并自动设置为电脑桌面背景(使用 URLDownloadToFile API函数)

    众所周知,bing搜索网站首页每日会更新一张图片,张张漂亮(额,也有一些不合我口味的),特别适合用来做电脑壁纸. 我们想要将bing网站背景图片设置为电脑桌面背景的通常做法是: 上网,搜索bing 找 ...

  3. Delphi调用爷爷类的方法(重新构造TMethod的data和code部分,其中Code指向祖父类的方法)

    Delphi通过inherited 可以调用父类的方法,但是没有提供直接调用父类的父类的方法(爷爷类),通过变通的方式实现如下: 假设父类是TFather,爷爷类TGrand,调用爷爷类的Write方 ...

  4. 压缩大文件时如何限制CPU使用率?----几种CPU资源限制方法的测试说明

    一.说明 我们的MySQL实例在备份后需要将数据打包压缩,部分低配机器在压缩时容易出现CPU打满导致报警的情况,需要在压缩文件时进行CPU资源的限制. 因此针对此问题进行了相关测试,就有了此文章. 二 ...

  5. Perl Scripts / 脚本

    树状递归列出目录下面子目录和文件 #!/usr/bin/perl #List all files and sub-directories as tree #Under current director ...

  6. autotools工具使用 good

    学习GNU/LINUX开发的编程人员,上手之后不久就会在编译开源软件的时候碰到configure脚本,过段时间还会知道configure脚本是 autoconf生成的:但是真正想用起来autoconf ...

  7. QT延时方法整理(QTimer::singleShot,QWaitCondition,QDateTime.secsTo三种新方法)

    1: void QTimer::singleShot ( int msec, QObject * receiver, const char * member ) [static] 样例: #inclu ...

  8. Voovan 是一个高性能异步网络框架和 HTTP(Java)

    Voovan 是一个高性能异步网络框架和 HTTP 服务器框架,同时支持 HTTP 客户端抓取.动态编译支持.数据库访问封装以及 DateTime.String.Log.反射.对象工具.流操作.文件操 ...

  9. SQL基础复习2

    一.视图 1.创建视图      创建视图后加 WITH CHECK OPTION 2.视图查询 数据库系统的处理方法: 视图消解法(View Resolution) 步骤: 进行有效性检查-> ...

  10. Java基础(六) static五大应用场景

    static和final是两个我们必须掌握的关键字.不同于其他关键字,他们都有多种用法,而且在一定环境下使用,可以提高程序的运行性能,优化程序的结构.上一个章节我们讲了final关键字的原理及用法,本 ...