【发布时间】:2014-08-06 09:14:57
【问题描述】:
考虑为按钮添加 ClickEvent- 和 PreviewMouseLeftButtonDown-Handler
<Button x:Name="button"
Click="Button_Click"
PreviewMouseLeftButtonDown="Button_PreviewMouseLeftButtonDown">
</Button>
单击按钮时,首先触发 PreviewMouseLeftButtonDown,然后触发 Click-Event。
如果您在 Preview...-Event 中设置 e.Handled = true,则不再处理 Click-Event。
但是,现在让我们考虑一下 MouseLeftButtonDownEvent。
首先,这个事件的路由策略是直接的。也就是说,每次控制都会重新加注。相比之下,Preview...-Event 是隧道式的,Click-Event 是冒泡的。
其次,添加 MouseLeftButtonDownEventHandler 仅在注册处理程序时才成功,以便甚至为已处理的事件调用它,如以下代码摘录所示。
button.AddHandler(MouseLeftButtonDownEvent,
new MouseButtonEventHandler(Button_MouseLeftButtonDown),
true);
我编写了一个测试应用程序,有一个按钮,并为每个事件添加了一个处理程序。当调用事件处理程序时,它会将一些信息写入文本块。
- 当我单击按钮时,将调用所有三个事件处理程序。
- 当我将
e.Handled = true添加到Preview...-EventHandler 时,只会调用此事件处理程序。尽管我已将UIElement.AddHandler handledEventsToo设置为 true,但即使是 Mouse...-EventHandler 也没有引发。 - 当我将
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);
}
【问题讨论】:
标签: wpf events event-handling eventhandler routedevent