4

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

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

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

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

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

以下是我使用Snoop获得的路由事件详细信息:

点击按钮1:

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

单击项目 1:

(Window)
> (Border)

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

我在这里想念什么?

4

1 回答 1

6

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

<ControlTemplate>
    <ItemsPresenter />
</ControlTemplate>

然后,您的自定义控件将无法单独进行命中测试。即使你有一个 ControlTemplate 像:

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

然后,如果 Background 为空,那么您的控件将无法单独进行命中测试。如果您只是将 Background 属性设置为透明,那么它将是可命中测试的。

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

于 2011-06-18T17:45:00.200 回答