WPF 入门笔记之事件
一、事件路由
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 入门笔记之事件的更多相关文章
- WPF 学习笔记 路由事件
1. 可传递的消息: WPF的UI是由布局组建和控件构成的树形结构,当这棵树上的某个节点激发出某个事件时,程序员可以选择以传统的直接事件模式让响应者来响应之,也可以让这个事件在UI组件树沿着一定的方向 ...
- WPF 入门笔记之基础
一.创建WPF程序 1. App.xaml 相当于窗体的配置文件 2. xmlns:xml名称空间的缩写 xmlns="http://schemas.microsoft.com/winfx/ ...
- WPF 入门笔记之控件内容控件
一.控件类 在WPF中和用户交互的元素,或者说.能够接受焦点,并且接收键盘鼠标输入的元素所有的控件都继承于Control类. 1. 常用属性: 1.1 Foreground:前景画刷/前景色(文本颜色 ...
- WPF 入门笔记之布局
一.布局原则: 1. 不应显示的设定元素的尺寸,反而元素可以改变它的尺寸,并适应它们的内容 2. 不应使用平布的坐标,指定元素的位置. 3. 布局容器和它的子元素是共享可以使用的空间 4. 可以嵌套的 ...
- 《深入浅出WPF》笔记——事件篇
如果对事件一点都不了解或者是模棱两可的话,建议先去看张子阳的委托与事件的文章(比较长,或许看完了,也忘记看这一篇了,没事,我会原谅你的)http://www.cnblogs.com/JimmyZhan ...
- WPF入门:数据绑定
上一篇我们将XAML大概做了个了解 ,这篇将继续学习WPF数据绑定的相关内容 数据源与控件的Binding Binding作为数据传送UI的通道,通过INotityPropertyChanged接口的 ...
- React.js入门笔记
# React.js入门笔记 核心提示 这是本人学习react.js的第一篇入门笔记,估计也会是该系列涵盖内容最多的笔记,主要内容来自英文官方文档的快速上手部分和阮一峰博客教程.当然,还有我自己尝试的 ...
- WPF入门教程系列三——Application介绍(续)
接上文WPF入门教程系列二——Application介绍,我们继续来学习Application 三.WPF应用程序的关闭 WPF应用程序的关闭只有在应用程序的 Shutdown 方法被调用时,应用程序 ...
- WPF入门教程系列(二) 深入剖析WPF Binding的使用方法
WPF入门教程系列(二) 深入剖析WPF Binding的使用方法 同一个对象(特指System.Windows.DependencyObject的子类)的同一种属性(特指DependencyProp ...
随机推荐
- Delphi 10.2可以开发Linux桌面应用了
原始地址 https://community.embarcadero.com/blogs/entry/firemonkey-on-linux Delphi Linux编译器已经发布,现在无需等待 ...
- 获取bing图片并自动设置为电脑桌面背景(使用 URLDownloadToFile API函数)
众所周知,bing搜索网站首页每日会更新一张图片,张张漂亮(额,也有一些不合我口味的),特别适合用来做电脑壁纸. 我们想要将bing网站背景图片设置为电脑桌面背景的通常做法是: 上网,搜索bing 找 ...
- Delphi调用爷爷类的方法(重新构造TMethod的data和code部分,其中Code指向祖父类的方法)
Delphi通过inherited 可以调用父类的方法,但是没有提供直接调用父类的父类的方法(爷爷类),通过变通的方式实现如下: 假设父类是TFather,爷爷类TGrand,调用爷爷类的Write方 ...
- 压缩大文件时如何限制CPU使用率?----几种CPU资源限制方法的测试说明
一.说明 我们的MySQL实例在备份后需要将数据打包压缩,部分低配机器在压缩时容易出现CPU打满导致报警的情况,需要在压缩文件时进行CPU资源的限制. 因此针对此问题进行了相关测试,就有了此文章. 二 ...
- Perl Scripts / 脚本
树状递归列出目录下面子目录和文件 #!/usr/bin/perl #List all files and sub-directories as tree #Under current director ...
- autotools工具使用 good
学习GNU/LINUX开发的编程人员,上手之后不久就会在编译开源软件的时候碰到configure脚本,过段时间还会知道configure脚本是 autoconf生成的:但是真正想用起来autoconf ...
- QT延时方法整理(QTimer::singleShot,QWaitCondition,QDateTime.secsTo三种新方法)
1: void QTimer::singleShot ( int msec, QObject * receiver, const char * member ) [static] 样例: #inclu ...
- Voovan 是一个高性能异步网络框架和 HTTP(Java)
Voovan 是一个高性能异步网络框架和 HTTP 服务器框架,同时支持 HTTP 客户端抓取.动态编译支持.数据库访问封装以及 DateTime.String.Log.反射.对象工具.流操作.文件操 ...
- SQL基础复习2
一.视图 1.创建视图 创建视图后加 WITH CHECK OPTION 2.视图查询 数据库系统的处理方法: 视图消解法(View Resolution) 步骤: 进行有效性检查-> ...
- Java基础(六) static五大应用场景
static和final是两个我们必须掌握的关键字.不同于其他关键字,他们都有多种用法,而且在一定环境下使用,可以提高程序的运行性能,优化程序的结构.上一个章节我们讲了final关键字的原理及用法,本 ...