考虑为按钮添加 ClickEvent- 和 PreviewMouseLeftButtonDown-Handler
<Button x:Name="button"
Click="Button_Click"
PreviewMouseLeftButtonDown="Button_PreviewMouseLeftButtonDown">
</Button>
单击按钮时,首先会触发 PreviewMouseLeftButtonDown,然后触发 Click-Event。
如果您e.Handled = true
在 Preview...-Event 中设置,则不再处理 Click-Event。
但是,现在让我们考虑一下 MouseLeftButtonDownEvent。
首先,这个事件的路由策略是直接的。也就是说,每次控制都会重新加注。相反,Preview...-Event 是隧道式的,Click-Event 是冒泡的。
其次,添加 MouseLeftButtonDownEventHandler 仅在注册处理程序时才会成功,以便甚至为已处理的事件调用它,如以下代码摘录所示。
button.AddHandler(MouseLeftButtonDownEvent,
new MouseButtonEventHandler(Button_MouseLeftButtonDown),
true);
我编写了一个测试应用程序,有一个按钮,并为每个事件添加了一个处理程序。当调用事件处理程序时,它会将一些信息写入文本块。
- 当我单击该按钮时,将调用所有三个事件处理程序。
- 当我添加
e.Handled = true
到 Preview...-EventHandler 时,只会调用此事件处理程序。甚至 Mouse...-EventHandler 也没有被提升,尽管我已经设置UIElement.AddHandler handledEventsToo
为 true。 - 当我添加
e.Handled = true
到 Mouse...-EventHandler 时,会调用所有三个事件处理程序。
这对我来说没有任何意义。Mouse...-EventHandlers 不会影响 Click-EventHandlers,但 Preview...-EventHandlers 会影响 Mouse...- 和 Click-EventHandlers。
甚至“强制”处理鼠标事件失败...-EventHandler。
实际上,我从没想过不同类型的事件处理程序会相互影响。我的理解是,如果我有一个 Preview...-Event 和一个 Click-Event,它们是独立的。
那么,我错过了什么?
这是非常简单的示例代码:
XAML:
<DockPanel>
<Border x:Name="border" DockPanel.Dock="Top" Height="50"
BorderBrush="Gray" BorderThickness="1">
<StackPanel x:Name="stackpanel" Background="LightGray"
Orientation="Horizontal" HorizontalAlignment="Center">
<Button x:Name="button" Width="Auto"
PreviewMouseLeftButtonDown="Button_PreviewMouseLeftButtonDown">
Click Me
</Button>
</StackPanel>
</Border>
<Border DockPanel.Dock="Bottom" BorderBrush="Gray" BorderThickness="1">
<ScrollViewer>
<TextBlock x:Name="textBlock" TextWrapping="Wrap"/>
</ScrollViewer>
</Border>
</DockPanel>
代码隐藏:
public MainWindow()
{
InitializeComponent();
button.AddHandler(MouseLeftButtonDownEvent, new MouseButtonEventHandler(Button_MouseLeftButtonDown), true);
button.AddHandler(ButtonBase.ClickEvent, new RoutedEventHandler(Button_Click), true);
stackpanel.AddHandler(ButtonBase.ClickEvent, new RoutedEventHandler(Button_Click), true /*false*/ );
}
private void Output(object sender, RoutedEventArgs e)
{
textBlock.Text += "RoutedEvent: " + e.RoutedEvent + "\n";
textBlock.Text += "Sender: " + sender + "\n";
textBlock.Text += "Source: " + e.Source + "\n";
textBlock.Text += "OriginalSource: " + e.OriginalSource + "\n" + "\n";
}
private void Button_Click(object sender, RoutedEventArgs e)
{
// e.Handled = true;
Output(sender, e);
}
private void Button_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
// e.Handled = true;
Output(sender, e);
}
private void Button_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
Output(sender, e);
}