WPF RoutedEvent and HitTest - 简书
原文:WPF RoutedEvent and HitTest - 简书
学习的时候切忌心浮气躁,慢慢的过每一个知识点,不要漏掉任何细节。不然当遇到细节问题的时候,会恼,会闹,会悔不该当初——花一下午调bug最后只改了一个参数有感。
相信很多用过WPF的人都知道WPF中的路由事件。一般看书的话,这个知识点也会在前几章讲到。总的来说,也就是
- WPF的控件都存在于一颗Visual tree当中。
- 事件在控件中的传递,其实也就是事件在Visual tree中的传递
- 隧道事件从上往下,由树根开始向叶子传播
- 冒泡事件从下往上,由子节点开始向根传播
假设我们有一个Visual tree长这样:
MainWindow
|_Border
|_Grid
|_TextBlock
那么如果用户点击了TextBlock。那么会产生什么事件,然后会怎么传递呢?
答案是
- 会产生
PreviewMouseDown和MouseDown事件 PreviewMouseDown是隧道事件,事件的顺序是MainWindow->Border->Grid->TextBlockMouseDown是冒泡事件,事件的顺序与之前相反,是TextBlock->Grid->Border->MainWindow
Tips:
如何查看WPF中的事件?有一个开源工具snoop可以帮助你。下图是一个实际示例,UI结构以及操作和上述一致。example
好,我们再看一个例子。
MainWindow
|_Border
|_Grid
|_TextBlock(Margin="32")
和上个例子不同的地方在于,我们把TextBlock的边距扩大了。这就意味着,我们可以点击在TextBlock的边距上,那么会发生什么呢?先自己想想哦。
注意这里的border是window中自带的,不是我们自己声明的。所以正确答案是,只传播到了
MainWindow。为了区别,我给声明的Border随便起了个名字。
要是答对了的同学,那不是一般的棒!
我们这里有两个问题:
PreviewMouseDown只传递到了MainWindow。作为一个隧道事件,没有继续往下传递。- 触发事件的是
MainWindow,不是Border也不是Grid。
先解答第一个问题。路由事件的准确触发顺序应该是
- 隧道事件从根开始,传播到产生事件的控件为止。如果中间有控件处理(
e.Handled = true)掉,就停止传播。 - 冒泡事件从产生事件的控件开始,传播到根节点为止。如果中间有控件处理(
e.Handled = true)掉,就停止传播。 - 系统提供的Preview事件先触发。如果被处理(
e.Handled = true)掉,不会在产生对应的冒泡事件。
第二个问题就很恼人了。总的来说就是
- 如果没有控件没有被渲染,那么该控件不能被HitTest,也不能被路由事件触发。(参见这里)
也就是说,Border和Grid没能触发,是因为他们没有Background,没有被渲染。如果加上,即使你加的是TransParent,也会有效。添加了TransParent为Border的背景添加了TransParent为Grid的背景
也就是说,如果你希望下面的控件能够触发事件。那么让上面的控件不能被HitTest就可以了。我今天遇到的坑是,上面一层自己画的一个框,用的函数是
dc.DrawGeometry(Brushes.Transparent, new Pen(brush, GraphicsLineWidth), PathGeometry);
改成
dc.DrawGeometry(null, new Pen(brush, GraphicsLineWidth), PathGeometry);
就好了。
WPF RoutedEvent and HitTest - 简书的更多相关文章
- WPF ControllTemplate Triggers小记 - 简书
原文:WPF ControllTemplate Triggers小记 - 简书 WPF中,样式模板中如果定义EventTrigger事件方式实现动画.那么需要注意两点: 1.对于绑定的属性的Event ...
- WPF 任务栏颜色 - 简书
原文:WPF 任务栏颜色 - 简书 先看看效果,这种效果可以用来做进度条或者消息通知闪烁. image.png image.png image.png image.png 有一个好消息 ...
- WPF之路-键盘与鼠标事件 - 简书
原文:WPF之路-键盘与鼠标事件 - 简书 键盘事件 事件类型分为以下几个类型 生命周期事件:在元素加载与卸载的时候发生 鼠标事件:鼠标动作 键盘事件:键盘动作 手写笔事件:适用于win7以上的系统 ...
- WPF 动画:同为控件不同命 - 简书
原文:WPF 动画:同为控件不同命 - 简书 1. 及格与优秀 读大学的时候,有一门课的作业是用 PPT 展示. 但是我们很多同学都把 PPT 当做 Word 来用,就单纯地往里面堆文字. 大家都单纯 ...
- WPF使用IDataErrorInfo接口进行数据校验 - 简书
原文:WPF使用IDataErrorInfo接口进行数据校验 - 简书 class ValidationBindableBase : BindableBase, IDataErrorInfo { pu ...
- c#字符串加载wpf控件模板代码 - 简书
原文:c#字符串加载wpf控件模板代码 - 简书 ResourceManager resManagerA = new ResourceManager("cn.qssq666.Properti ...
- WPF中Popup控件在Win7以及Win10等中的对齐点方式不一样的解决方案 - 简书
原文:WPF中Popup控件在Win7以及Win10等中的对齐点方式不一样的解决方案 - 简书 最近项目中使用弹出控件Popup,发现弹出框的对齐方式在不同的系统中存在不同(Popup在win10上是 ...
- WPF系列教程——(三)使用Win10 Edge浏览器内核 - 简书
原文:WPF系列教程--(三)使用Win10 Edge浏览器内核 - 简书 在需要显示一些 H5网站的时候自带的WebBrowser总是显示不了,WebBrowser使用的是IE内核,许多H5新特性都 ...
- WPF系列教程——(一)仿TIM QQ界面 - 简书
原文:WPF系列教程--(一)仿TIM QQ界面 - 简书 TIM QQ 我们先来看一下TIM QQ长什么样,整体可以将界面分为三个部分 TIM QQ 1. 准备 阅读本文假设你已经有XAML布局的基 ...
随机推荐
- JavaScript --- Set 集合结构详解
Set 对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用. 1 const set1 = new Set([1, 2, 3, 4, 5]); 2 3 console.log(set1.has ...
- Django settings.py 的media路径设置
转载自:http://www.xuebuyuan.com/676599.html 在一个 models 中使用 FileField 或 ImageField 需要以下步骤: 1. 在你的 settin ...
- ERROR: Repository not found. ////Git, but is not registered in the Settings.
1.ERROR: Repository not found. 这个问题是因为在你推送的github账户中,并没有这个Repository. 解决方法: 1)检查自己的github中的Repositor ...
- 在64位Ubuntu上编译32位程序常见错误
问 题1: 找不到头文件 asm/errno.h 解决办法 : [/usr/lib/gcc$ ]sudo ln -s x86_64-linux-gnu/asm asm 问题2:找不到gcc ...
- 新闻cms管理系统功能介绍
一. 后台登录功能 1.后台登录 2.数据校验 3. dialog插件 4.layer插件 5. 退出登录(利用session失效) 二. 菜单管理 1.后台入口文件优化 2.公共文件引入 3.菜单的 ...
- Linux Shell常用技巧(九)
十九. 和系统运行进程相关的Shell命令: 1. 进程监控命令(ps): 要对进程进行监测和控制,首先必须要了解当前进程的情况,也就是需要查看当前进程,而ps命令就是最基本同时 ...
- PDO介绍(16)
安装PDO PDO的数据选项 链接到数据库服务器并选择数据库 错误处理 获取和设置属性 查询执行 准备语句介绍 获取数据 设置绑定列 处理事务
- 理解Web应用程序的代码结构和运行原理(3)
1.理解Web应用程序的运行原理和机制 Web应用程序是基于浏览器/服务器模式(也称B/S架构)的应用程序,它开发完成后,需要部署到Web服务器上才能正常运行,与用户交互的客户端是网页浏览器. 浏览器 ...
- Linux-- 文件编辑器 vi/vim(1)
初识 vi/vim 文本编辑器 1.vi 和 vim 相同,都是文本编辑器,在 vi 模式下可以查看文本,编辑文本,是 Linux 最常用的命令,vi 模式下分为三部分,第一部分一般模式,在一般模式中 ...
- 2019年,iOS开发的你不可或缺的进阶之路!
序言 我相信很多人都在说,iOS行业不好了,iOS现在行情越来越难了,失业的人比找工作的人还要多.失业即相当于转行,跳槽即相当于降低自己的身价.那么做iOS开发的你,你是否在时刻准备着跳槽或者转行了. ...
