我对 WPF 比较陌生。我试图了解 MouseDownEvent 和 PreviewMouseDownEvent 之间的区别。
我了解 WPF 事件策略,并且我了解 MouseDown 事件是一个冒泡事件,而 PreviewMouseDown 是一个隧道事件。
我也了解这些事件被触发的顺序 - 根据这个 MSDN 概述http://msdn.microsoft.com/en-us/library/ms742806.aspx#routing(那里有一个带有示例的图表)。
所以我尝试编写一些自己的代码,例如检查一下:
<Grid x:Name="grid" Width="250">
<StackPanel Mouse.MouseDown="StackPanel_MouseDown" PreviewMouseDown="StackPanel_PreviewMouseDown">
<WPFVisualizerExample:MyButton x:Name="B1" PreviewMouseDown="B1_PreviewMouseDown" MouseDown="B1_MouseDown" Margin="5,5,5,5">
<WPFVisualizerExample:MyButton x:Name="B2" PreviewMouseDown="B2_PreviewMouseDown" MouseDown="B2_MouseDown" Margin="5,5,5,5">
<WPFVisualizerExample:MyButton x:Name="B3" PreviewMouseDown="B3_PreviewMouseDown" MouseDown="B3_MouseDown" Margin="5,5,5,5">Click Me</WPFVisualizerExample:MyButton>
</WPFVisualizerExample:MyButton>
</WPFVisualizerExample:MyButton>
</StackPanel>
</Grid>
我对每个事件(预览和非预览)都有一个事件处理程序,我想看看发生了什么,哪个事件被抛出(我为每个事件显示了一个消息框)。
'MyButton' 用户控件只是扩展了基本 Button 并覆盖 OnMouseDown 和 OnPreviewMouseDown 以将 e.Handled 设置为 false:
protected override void OnMouseDown(System.Windows.Input.MouseButtonEventArgs e)
{
base.OnMouseDown(e);
e.Handled = false;
}
protected override void OnPreviewMouseDown(System.Windows.Input.MouseButtonEventArgs e)
{
base.OnPreviewMouseDown(e);
e.Handled = false;
}
(尝试了这个和没有这个)。
根据 MSDN 概述(在上面的链接中),如果我有 3 个元素,那么事件路由应如下所示:
根元素上的 PreviewMouseDown(隧道)。
中间元素 #1 上的 PreviewMouseDown(隧道)。
源元素 #2 上的 PreviewMouseDown(隧道)。
源元素 #2 上的 MouseDown(气泡)。
中间元素 #1 上的 MouseDown(气泡)。
根元素上的 MouseDown(气泡)。
所以我希望消息框按照上面的方式显示。由于某种原因 - 我不明白只有预览事件被抛出(根据 MSDN 所说的 Preview_B1=>Preview_B2=>Preview_B3)。我的期望是:Preview_B1=>Preview_B2=>Preview_B3=>NonPreview_B3=>NonPreview_B2=>NonPreview_B1。
但是根本没有抛出非预览事件。
所以基本上我不了解事件的路线,从 MSDN 概述中我了解到路线从根元素开始,向下(隧道)到源元素,然后备份(气泡)到根元素,但是这个不是在实践中发生的事情。
了解这些事件是如何运作的对我来说非常重要,我可能在这里错过了一些基本的东西,我们将不胜感激。
谢谢!!-吉利