我的应用程序上有以下树:
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)
该事件从未被报告为已处理,因此据我所知,它应该继续进行隧道传输。
我在这里缺少什么?
最佳答案
您需要确保您的自定义控件是可 HitTest 的。如果您有一个类似的 ControlTemplate:
<ControlTemplate>
<ItemsPresenter />
</ControlTemplate>
那么您的自定义控件本身将无法进行 HitTest 。即使您有一个像这样的 ControlTemplate:
<ControlTemplate>
<Border Background="{TemplateBinding Background}" ...>
<ItemsPresenter />
</Border>
</ControlTemplate>
然后,如果Background 为null,那么您的控件本身将无法进行 HitTest 。如果您只需将“背景”属性设置为“透明”,那么它将是可 HitTest 的。
经验法则是,如果您的控件或其后代之一没有在给定位置(即像素)渲染某些内容,即使它是透明的,那么鼠标也不会为其注册事件。
关于wpf - PreviewMouseDown 未按预期进行隧道传输,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6395525/