ScrollViewer 中的画布(预览)MouseButtonDown 事件顺序
如果我们有
<ScrollViewer Name="scroll_viewer" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Canvas Name="canvas" Height="200" Width="200">
<Rectangle Fill="AliceBlue" Width="100" Height="100"/>
</Canvas>
</ScrollViewer>
以下处理程序:
scroll_viewer.PreviewMouseLeftButtonDown
scroll_viewer.MouseLeftButtonDown
canvas.PreviewMouseLeftButtonDown
那么如果我们单击矩形,我们首先调用 scroll_viewer_PreviewMouseLeftButtonDown
,然后调用 canvas_PreviewMouseLeftButtonDown
,但不会调用 scroll_viewer_MouseLeftButtonDown
。
我想首先在画布中处理单击事件 - 如果单击对象,我想处理该事件(用于对象拖动)。如果没有单击画布对象,我想处理scroll_viewer中的事件(以使用鼠标管理滚动视图平移)。
鉴于调用顺序与我想要的相反并且未调用非预览版本 scroll_viewer.MouseLeftButtonDown
,如何管理此问题?
更新:
从这篇文章: Silverlight 论坛
((FrameworkElement)scroll_viewer.GetValue(ScrollViewer.ContentProperty)).MouseLeftButtonDown += scroll_viewer_MouseLeftButtonDown;
确实有效,即预览活动后确实会被调用 -有人可以解释为什么需要这种不太明显的语法吗?
If we have
<ScrollViewer Name="scroll_viewer" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Canvas Name="canvas" Height="200" Width="200">
<Rectangle Fill="AliceBlue" Width="100" Height="100"/>
</Canvas>
</ScrollViewer>
with handlers for:
scroll_viewer.PreviewMouseLeftButtonDown
scroll_viewer.MouseLeftButtonDown
canvas.PreviewMouseLeftButtonDown
Then if we click in the Rectangle we get scroll_viewer_PreviewMouseLeftButtonDown
called first then canvas_PreviewMouseLeftButtonDown
but scroll_viewer_MouseLeftButtonDown
is not called.
I want to handle the click event first in the canvas - if an object is clicked I want to handled the event (for object drag). If no canvas object is clicked I want to handle event in scroll_viewer (to manage scrollview panning with the mouse).
How to manage this given that the call order is the oposite of what i want and that the non perview version scroll_viewer.MouseLeftButtonDown
is not called?
UPDATE:
From this post: Silverlight forums
((FrameworkElement)scroll_viewer.GetValue(ScrollViewer.ContentProperty)).MouseLeftButtonDown += scroll_viewer_MouseLeftButtonDown;
DOES work ie does get called after the preview events - can some explain why this less than obvious syntax is required?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
![扫码二维码加入Web技术交流群](/public/img/jiaqun_03.jpg)
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
问题是 ScrollViewer 已经在内部处理了 MouseLeftButtonDown 事件,如下所示:
您可以使用自定义类“修复”此问题,如下所示:
旁注:您应该在 XAML 中使用
x:Name
,而不是Name
。否则,使用上述类可能会遇到编译错误。或者,您可以为所有
MouseLeftButtonDown
事件(包括已处理的事件)附加处理程序。因此,您可以使用:
The problem is that the
ScrollViewer
already handles theMouseLeftButtonDown
event internally, like so:You can "fix" this using a custom class, like so:
SIDE NOTE: You should use
x:Name
in XAML, notName
. Otherwise you may run into compilation errors using the above class.Alternatively, you could attach your handler for all
MouseLeftButtonDown
events, including handled ones. So instead of:You'd use:
Preview
事件遵循与Tunneling
策略类似的路由策略,这意味着事件从元素树的顶部开始,然后向下传播。因此它会首先到达您的 ScrollViewer,然后到达您的 Canvas。非预览事件遵循类似于冒泡策略的路由策略,这意味着事件从它们发生的对象开始,并沿元素树向上传播。在这种情况下,Canvas 将首先受到攻击,然后是 ScrollViewer。
路由策略的更多信息
您可以在此处阅读有关 要使 Canvas 对象对 HitTest 事件可见,它们需要具有不透明的背景。因此,如果您有一个未指定背景颜色的画布,它将默认为透明,并且对 HitTest 不可见。
The
Preview
events follow a routing strategy similar to theTunneling
strategy, meaning that the event starts at the top of the element tree, and travels down it. So it would hit your ScrollViewer first, then your Canvas.The non-Preview events follow a routing strategy similar to the
Bubbling
strategy, meaning that events start on the object they occurred on, and travel up the element tree. In this case, the Canvas would get hit first, then the ScrollViewer.You can read more about the Routing strategies here
As a side note, for Canvas objects to be visible for HitTest events, they need to have a non-transparent background. So if you have a Canvas with no background color specified, it will default to Transparent and not be visible for HitTests.