4

如果我们有

<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

然后,如果我们单击 Rectangle,我们scroll_viewer_PreviewMouseLeftButtonDown首先会被调用,canvas_PreviewMouseLeftButtonDownscroll_viewer_MouseLeftButtonDown不会被调用。
我想首先在画布中处理单击事件 - 如果单击一个对象,我想处理该事件(用于对象拖动)。如果没有单击画布对象,我想处理 scroll_viewer 中的事件(以管理使用鼠标进行滚动视图平移)。鉴于调用顺序与我想要的相反并且未调用
非 perview 版本,如何管理这一点?scroll_viewer.MouseLeftButtonDown

更新:
来自这篇文章:Silverlight 论坛

((FrameworkElement)scroll_viewer.GetValue(ScrollViewer.ContentProperty)).MouseLeftButtonDown += scroll_viewer_MouseLeftButtonDown;

确实有效,即在预览事件之后确实被调用 - 有人可以解释为什么需要这种不太明显的语法吗?

4

2 回答 2

6

问题是ScrollViewer已经在内部处理了MouseLeftButtonDown事件,如下所示:

protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) {
    if (base.Focus())
        e.Handled = true;
    base.OnMouseLeftButtonDown(e);
}

您可以使用自定义类“修复”此问题,如下所示:

public class MyScrollViewer : ScrollViewer {

    protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) {
        base.OnMouseLeftButtonDown(e);
        e.Handled = false;
    }
}

旁注:您应该x:Name在 XAML 中使用,而不是Name. 否则,您可能会在使用上述类时遇到编译错误。

或者,您可以为所有事件附加您的处理程序MouseLeftButtonDown,包括已处理的事件。所以而不是:

this.scroll_viewer.MouseLeftButtonDown += new MouseButtonEventHandler(scroll_viewer_MouseLeftButtonDown);

你会使用:

this.scroll_viewer.AddHandler(ScrollViewer.MouseLeftButtonDownEvent, new MouseButtonEventHandler(this.scroll_viewer_MouseLeftButtonDown), true);
于 2011-10-28T14:10:06.787 回答
2

Preview事件遵循类似于策略的路由策略,Tunneling这意味着事件从元素树的顶部开始,并沿着它向下传播。所以它会先击中你的 ScrollViewer,然后是你的 Canvas。

非预览事件遵循类似于策略的路由策略Bubbling,这意味着事件从它们发生的对象开始,并沿着元素树向上传播。在这种情况下,Canvas 将首先被击中,然后是 ScrollViewer。

您可以在此处阅读有关路由策略的更多信息

附带说明一下,要让 Canvas 对象对 HitTest 事件可见,它们需要具有非透明背景。因此,如果您有一个没有指定背景颜色的 Canvas,它将默认为透明并且对 HitTest 不可见。

于 2011-10-28T14:11:27.470 回答