原文:WPF RoutedEvent and HitTest - 简书

学习的时候切忌心浮气躁,慢慢的过每一个知识点,不要漏掉任何细节。不然当遇到细节问题的时候,会恼,会闹,会悔不该当初——花一下午调bug最后只改了一个参数有感。

相信很多用过WPF的人都知道WPF中的路由事件。一般看书的话,这个知识点也会在前几章讲到。总的来说,也就是

  • WPF的控件都存在于一颗Visual tree当中。
  • 事件在控件中的传递,其实也就是事件在Visual tree中的传递
  • 隧道事件从上往下,由树根开始向叶子传播
  • 冒泡事件从下往上,由子节点开始向根传播

假设我们有一个Visual tree长这样:

MainWindow
|_Border
|_Grid
|_TextBlock

那么如果用户点击了TextBlock。那么会产生什么事件,然后会怎么传递呢?

答案是

  1. 会产生PreviewMouseDownMouseDown事件
  2. PreviewMouseDown是隧道事件,事件的顺序是MainWindow->Border->Grid->TextBlock
  3. MouseDown是冒泡事件,事件的顺序与之前相反,是TextBlock->Grid->Border->MainWindow

Tips:

如何查看WPF中的事件?有一个开源工具snoop可以帮助你。下图是一个实际示例,UI结构以及操作和上述一致。

example

好,我们再看一个例子。

MainWindow
|_Border
|_Grid
|_TextBlock(Margin="32")

和上个例子不同的地方在于,我们把TextBlock的边距扩大了。这就意味着,我们可以点击在TextBlock的边距上,那么会发生什么呢?先自己想想哦。

正确答案

注意这里的border是window中自带的,不是我们自己声明的。所以正确答案是,只传播到了MainWindow。为了区别,我给声明的Border随便起了个名字。

要是答对了的同学,那不是一般的棒!

我们这里有两个问题:

  1. PreviewMouseDown只传递到了MainWindow。作为一个隧道事件,没有继续往下传递。
  2. 触发事件的是MainWindow,不是Border也不是Grid

先解答第一个问题。路由事件的准确触发顺序应该是

  1. 隧道事件从根开始,传播到产生事件的控件为止。如果中间有控件处理(e.Handled = true)掉,就停止传播。
  2. 冒泡事件从产生事件的控件开始,传播到根节点为止。如果中间有控件处理(e.Handled = true)掉,就停止传播。
  3. 系统提供的Preview事件先触发。如果被处理(e.Handled = true)掉,不会在产生对应的冒泡事件。

第二个问题就很恼人了。总的来说就是

  • 如果没有控件没有被渲染,那么该控件不能被HitTest,也不能被路由事件触发。(参见这里

    也就是说,BorderGrid没能触发,是因为他们没有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 - 简书的更多相关文章

  1. WPF ControllTemplate Triggers小记 - 简书

    原文:WPF ControllTemplate Triggers小记 - 简书 WPF中,样式模板中如果定义EventTrigger事件方式实现动画.那么需要注意两点: 1.对于绑定的属性的Event ...

  2. WPF 任务栏颜色 - 简书

    原文:WPF 任务栏颜色 - 简书 先看看效果,这种效果可以用来做进度条或者消息通知闪烁.   image.png   image.png   image.png   image.png 有一个好消息 ...

  3. WPF之路-键盘与鼠标事件 - 简书

    原文:WPF之路-键盘与鼠标事件 - 简书 键盘事件 事件类型分为以下几个类型 生命周期事件:在元素加载与卸载的时候发生 鼠标事件:鼠标动作 键盘事件:键盘动作 手写笔事件:适用于win7以上的系统 ...

  4. WPF 动画:同为控件不同命 - 简书

    原文:WPF 动画:同为控件不同命 - 简书 1. 及格与优秀 读大学的时候,有一门课的作业是用 PPT 展示. 但是我们很多同学都把 PPT 当做 Word 来用,就单纯地往里面堆文字. 大家都单纯 ...

  5. WPF使用IDataErrorInfo接口进行数据校验 - 简书

    原文:WPF使用IDataErrorInfo接口进行数据校验 - 简书 class ValidationBindableBase : BindableBase, IDataErrorInfo { pu ...

  6. c#字符串加载wpf控件模板代码 - 简书

    原文:c#字符串加载wpf控件模板代码 - 简书 ResourceManager resManagerA = new ResourceManager("cn.qssq666.Properti ...

  7. WPF中Popup控件在Win7以及Win10等中的对齐点方式不一样的解决方案 - 简书

    原文:WPF中Popup控件在Win7以及Win10等中的对齐点方式不一样的解决方案 - 简书 最近项目中使用弹出控件Popup,发现弹出框的对齐方式在不同的系统中存在不同(Popup在win10上是 ...

  8. WPF系列教程——(三)使用Win10 Edge浏览器内核 - 简书

    原文:WPF系列教程--(三)使用Win10 Edge浏览器内核 - 简书 在需要显示一些 H5网站的时候自带的WebBrowser总是显示不了,WebBrowser使用的是IE内核,许多H5新特性都 ...

  9. WPF系列教程——(一)仿TIM QQ界面 - 简书

    原文:WPF系列教程--(一)仿TIM QQ界面 - 简书 TIM QQ 我们先来看一下TIM QQ长什么样,整体可以将界面分为三个部分 TIM QQ 1. 准备 阅读本文假设你已经有XAML布局的基 ...

随机推荐

  1. java构造方法-this关键字的用法

    public class constructor { public static void main(String[] args) { // TODO Auto-generated method st ...

  2. cocos2d-x3.0 后配置信息重置

    原文地址:http://blog.csdn.net/qqmcy/article/details/37722689 近期遇到这种一个问题,cocos设置setup.py中ndk.sdk.ant时设置的路 ...

  3. mysql5.6 函数大全

    # 数学函数(1)ABS(x)返回x的绝对值(2)PI()返回圆周率π,默认显示6位小数(3)SQRT(x)返回非负数的x的二次方根(4)MOD(x,y)返回x被y除后的余数(5)CEIL(x).CE ...

  4. 解决 mongodb $in needs an array 问题

    问题现象: 在mongodb执行批量查询操作时,抛出异常 Exception 2: $in needs an array. 问题解决: 感谢伟大的 google 和 stackoverflow 有人遇 ...

  5. 2019.3.25 IDEA控制台乱码解决 &&idea关闭代码自动提示

    设置Tomcat里面的conf文件夹下的properties结尾的文件

  6. docker 导出导入

    容器导出 docker export -o myname.tar 容器id 容器导人 docker import myname.tar httpd:v1

  7. PLSQL Developer 12 注册码

    PLSQL Developer 12 注册码product code: 4vkjwhfeh3ufnqnmpr9brvcuyujrx3n3le serial Number:226959 password ...

  8. 通达信k线颜色设置

    通达信的k线函数没有颜色选项.如果想要画颜色可以使用STICKLINE函数来覆盖当前k线这样也是可以满足需求. 第一步画针 STICKLINE(条件 , L , H , 0 , 0 ) , 颜色; 第 ...

  9. Spring boot 零配置开发微服务

    2018年12月29日星期六 体验Spring boot 零配置开发微服务 1.为什么要用Spring  boot? 1.1 简单方便.配置少.整合了大多数框架 1.2 适用于微服务搭建,搭建的微服务 ...

  10. c#网络传输

    接着前面简单讲的,给大家聊聊服务开发. 网络传输 先说网络传输开发,总体来说,可以看成4中模型 我们把传输过程看做网线,那么在通过传输的过程中.2边就涉及池化问题,也就是我们常见的异步传输. 在业务端 ...