Предположим, вы добавили 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 ...- событие туннелируется, 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.
И даже «принудительная» обработка события не удалась для Mouse. ..-Обработчик события.
На самом деле, я никогда не думал, что обработчики событий разных типов могут влиять друг на друга. Я понял, что если у меня есть 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);
}