PreviewMouseDown未按预期进行隧道传输

时间:2011-06-18 11:02:57

标签: wpf mouse routed-events

我的应用程序中有以下树:

MainWindow (Window)
> LayoutRoot (Grid)
  > (MyCustomControl)
    > Item1 (Grid)
      > Button (Button1)

MyCustomControl派生自ItemsControl,并在StackPanel上显示其项目。

MyCustomControl需要知道何时在其内部单击鼠标,因此我已经覆盖了OnPreviewMouseDown方法,并且希望得到通知我在控件内的任何鼠标按下。

会发生什么:如果我在Button1内部单击,则PreviewMouseDown事件沿树移动,并按预期执行OnPreviewMouseDown。但是,如果我点击Item1,则PreviewMouseDown事件会在MainWindow之后停止,甚至不会达到LayoutRoot。

以下是使用Snoop获得的路由事件详情:

点击Button1:

(Window)
> (Border)
  > (AdornerDecorator)
    > (ContentPresenter)
      > LayoutRoot (Grid)
        > (MyCustomControl)
          > (Border)
            > (StackPanel)
              > Item1 (Grid)
                > Button1 (Button)
                  > Chrome (ButtonChrome)

点击第1项:

(Window)
> (Border)

事件从未报告为已处理,因此据我所知,它应该继续进行隧道传输。

我在这里缺少什么?

1 个答案:

答案 0 :(得分:5)

您需要确保自定义控件是可以测试的。如果您有一个ControlTemplate,如:

<ControlTemplate>
    <ItemsPresenter />
</ControlTemplate>

然后您的自定义控件本身就不会受到测试。即使你有一个ControlTemplate,如:

<ControlTemplate>
    <Border Background="{TemplateBinding Background}" ...>
        <ItemsPresenter />
    </Border>
</ControlTemplate>

然后,如果Background为null,那么您的控件本身就不会是可测试的。如果您只是将Background属性设置为Transparent,那么它将是hit-testable。

经验法则是,如果你的控件或其中一个后代没有在给定位置(即像素)渲染某些东西,即使它是透明的,那么鼠标也不会为它注册事件。