Consider you add a ClickEvent- and PreviewMouseLeftButtonDown-Handler for a Button
<Button x:Name="button"
Click="Button_Click"
PreviewMouseLeftButtonDown="Button_PreviewMouseLeftButtonDown">
</Button>
When clicking the Button, first PreviewMouseLeftButtonDown is fired, then the Click-Event.
If you set e.Handled = true
in the Preview...-Event, the Click-Event is not handled any more.
However, now let's think of the MouseLeftButtonDownEvent.
First, this event's routing strategy is direct. That is, it is re-raised for every control. In contrast, the Preview...-Event is tunneling, the Click-Event is bubbling.
Second, adding a MouseLeftButtonDownEventHandler is only successful when registering the handler such that it is even invoked for already handled events, as shown in the following code excerpt.
button.AddHandler(MouseLeftButtonDownEvent,
new MouseButtonEventHandler(Button_MouseLeftButtonDown),
true);
I've written a test application, having a button, and added a handler for each of the Events. When an event handler is invoked, it writes some information into a text block.
- When I click the button, all three event handlers are invoked.
- When I add
e.Handled = true
to the Preview...-EventHandler, only this event handler is invoked. Even the Mouse...-EventHandler is not raised, although I've setUIElement.AddHandler handledEventsToo
to true. - When I add
e.Handled = true
to the Mouse...-EventHandler, all three event handlers are invoked.
That does not make any sense to me. Mouse...-EventHandlers do not affect the Click-EventHandlers, but Preview...-EventHandlers affect both Mouse...- and Click-EventHandlers.
And even 'forcing' to handle an event failed for the Mouse...-EventHandler.
Actually, I've never thought that event handlers of different types could affect each others. What I understood is that if I've got a Preview...-Event and a Click-Event, that these are independent.
So, what am I missing?
Here's the pretty simple sample code:
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>
Code-Behind:
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);
}