我的应用程序中有以下树:
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)
事件从未报告为已处理,因此据我所知,它应该继续进行隧道传输。
我在这里缺少什么?
答案 0 :(得分:5)
您需要确保自定义控件是可以测试的。如果您有一个ControlTemplate,如:
<ControlTemplate>
<ItemsPresenter />
</ControlTemplate>
然后您的自定义控件本身就不会受到测试。即使你有一个ControlTemplate,如:
<ControlTemplate>
<Border Background="{TemplateBinding Background}" ...>
<ItemsPresenter />
</Border>
</ControlTemplate>
然后,如果Background为null,那么您的控件本身就不会是可测试的。如果您只是将Background属性设置为Transparent,那么它将是hit-testable。
经验法则是,如果你的控件或其中一个后代没有在给定位置(即像素)渲染某些东西,即使它是透明的,那么鼠标也不会为它注册事件。