一、事件路由

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. Styling a ListView with a Horizontal ItemsPanel and a Header

    原文http://eblog.cloudplush.com/2012/05/23/styling-a-listview-with-a-horizontal-itemspanel-and-a-heade ...

  2. C# 桌面软件开发-深入学习 [1]- AY-C#人爱学不学-aaronyang技术分享

    原文:C# 桌面软件开发-深入学习 [1]- AY-C#人爱学不学-aaronyang技术分享 曾经我做office,不想依赖别人dll,就使用了 Type.GetTypeFromProgID 可以根 ...

  3. 安卓ImageButton圆角按钮设置

    首先图片要做成圆角的,使用美图秀秀,这个不多说. 之后使用设置了圆角的按钮,效果有缺陷,按钮会有灰色的边角. 类似这样: 去掉的方法是将layout的  android:src="@draw ...

  4. 『SHELL』--SHELL脚本执行方式(转)

    Shell脚本的执行方式: 注明:wd代表“脚本保存的目录” 1.fork 语法:/wd/shell.sh fork是最普通的, 就是直接在脚本里面用/wd/shell.sh来调用shell.sh这个 ...

  5. Standard C 语言标准函数库速查(彩色的函数列表,十分清楚)

    Standard C 语言标准函数库速查 (Cheat Sheet) wcstombs 函数说明 #include <stdlib.h> size_t mbstowcs(wchar_t * ...

  6. Ring3下无驱动移除winlogon.exe进程ctrl+alt+del,win+u,win+l三个系统热键,非屏蔽热键(子类化SAS 窗口)

    随手而作,纯粹技术研究,没什么实际意义. 打开xuetr,正常情况下.winlogon.exe注册了三个热键.ctrl+alt+del,win+u,win+l三个. 这三个键用SetWindowsHo ...

  7. 剖析Qt的事件机制原理(源代码级别)

    在用Qt写Gui程序的时候,在main函数里面最后依据都是app.exec();很多书上对这句的解释是,使Qt程序进入消息循环.下面我们就到exec()函数内部,来看一下他的实现原理.Let's go ...

  8. LFS Linux From Scratch 笔记(经验非教程)

    做了一个自己的DIY Linux系统.从编译每一行代码,建立每一个文件系统结构开始. 创造自己的GNU/Linux系统,不同于任何发行版.按照的教程是来自 linuxfromscratch.org 来 ...

  9. SYN2306A型 GPS北斗双模授时板

    SYN2306A型 GPS北斗双模授时板 北斗gps时钟北斗授时设备北斗时钟同步系统使用说明视频链接: http://www.syn029.com/h-pd-211-0_310_36_-1.html ...

  10. Redis相关面试题

    Reids:单线程+io多路复用机制 Redis与Memcached的区别: 一.memcached值是简单字符串,redis支持hash.set.list等复杂数据类型 二.redis可持久化数据, ...