标签:地方 pack href iter rap question web 细节 应该
原文:WPF RoutedEvent and HitTest - 简书学习的时候切忌心浮气躁,慢慢的过每一个知识点,不要漏掉任何细节。不然当遇到细节问题的时候,会恼,会闹,会悔不该当初——花一下午调bug最后只改了一个参数有感。
相信很多用过WPF的人都知道WPF中的路由事件。一般看书的话,这个知识点也会在前几章讲到。总的来说,也就是
假设我们有一个Visual tree长这样:
MainWindow
|_Border
|_Grid
|_TextBlock
那么如果用户点击了TextBlock
。那么会产生什么事件,然后会怎么传递呢?
答案是
PreviewMouseDown
和MouseDown
事件PreviewMouseDown
是隧道事件,事件的顺序是MainWindow
->Border
->Grid
->TextBlock
MouseDown
是冒泡事件,事件的顺序与之前相反,是TextBlock
->Grid
->Border
->MainWindow
Tips:
如何查看WPF中的事件?有一个开源工具snoop可以帮助你。下图是一个实际示例,UI结构以及操作和上述一致。
好,我们再看一个例子。
MainWindow
|_Border
|_Grid
|_TextBlock(Margin="32")
和上个例子不同的地方在于,我们把TextBlock
的边距扩大了。这就意味着,我们可以点击在TextBlock
的边距上,那么会发生什么呢?先自己想想哦。
注意这里的border是window中自带的,不是我们自己声明的。所以正确答案是,只传播到了
MainWindow
。为了区别,我给声明的Border
随便起了个名字。
要是答对了的同学,那不是一般的棒!
我们这里有两个问题:
PreviewMouseDown
只传递到了MainWindow
。作为一个隧道事件,没有继续往下传递。MainWindow
,不是Border
也不是Grid
。先解答第一个问题。路由事件的准确触发顺序应该是
e.Handled = true
)掉,就停止传播。e.Handled = true
)掉,就停止传播。e.Handled = true
)掉,不会在产生对应的冒泡事件。第二个问题就很恼人了。总的来说就是
Border
和Grid
没能触发,是因为他们没有Background
,没有被渲染。如果加上,即使你加的是TransParent
,也会有效。也就是说,如果你希望下面的控件能够触发事件。那么让上面的控件不能被HitTest就可以了。我今天遇到的坑是,上面一层自己画的一个框,用的函数是
dc.DrawGeometry(Brushes.Transparent, new Pen(brush, GraphicsLineWidth), PathGeometry);
改成
dc.DrawGeometry(null, new Pen(brush, GraphicsLineWidth), PathGeometry);
就好了。
WPF RoutedEvent and HitTest - 简书
标签:地方 pack href iter rap question web 细节 应该
原文地址:https://www.cnblogs.com/lonelyxmas/p/10682446.html