I understand how bubbling and tunneling works. However, i'm confused about using them. Here is why:
I want to handle a mouse click event. To bubble it, there is MouseDown
and, to tunnel it, there is PreviewMouseDown
. However, MouseDown
doesn't necessarily mean the user clicked the control. May be the user pressed the button and moved away from it to cancel the click.
I wouldn't want to change anything if the button is not being clicked.
So my question is, how are the Bubbling/Tunneling strategies useful?
If the event is listed RoutedEventArgs
, then it's routed event. Routed events support a RoutingStrategy of Bubble, Tunnel, or Direct. Let's take a look at the event handler of Button.Click
:
private void Grid_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Button Test clicked!");
}
There specified RoutedEventArgs
, so it's routed event. Because the preview were not specified in the name, therefore this Bubble event. This can be demonstrated in the following way:
<Grid ButtonBase.Click="Grid_Click">
<Button Name="TestButton" Width="100" Height="30" Content="Test" />
</Grid>
When you click on the TestButton
, the event is to rise above the Grid
, and displays a message:
Button Test clicked!
Usefulness of Bubbling/Tunneling strategies
Tunneling
Many of the standard controls listen to events, such as KeyDown
, MouseDown
, etc. For example -DataGrid
control. I want by pressing the enter key the function was called adding a record. But DataGrid
already has KeyDown
event, so the event is not raised. So you have to do your logic in the Tunnel event - PreviewKeyDown
, it will work before the KeyDown
event. The same applies to RichTextBoxControl
.
Bubbling
Sometimes, you need a global handler for a specific event, so it worked for all controls in VisualTree. Naturally, the a direct event you can not do it. Hence on the stage comes Bubbling event.
Another reason is the ideology of the WPF. This Button
can contain anything: Image
, another Button
, etc:
The user can click on the TextBlock/Image
in the Button
. How do we know that the click was in Button
? That's right, with the help of Bubbling event.
For more information, please see:
Understanding Routed Events and Commands In WPF
Edit
I changed little bit a Click
handler:
private void Grid_Click(object sender, RoutedEventArgs e)
{
String message = "#" + eventCounter.ToString() + ":\r\n" +
" Sender: " + sender.ToString() + ":\r\n" +
" Source: " + e.Source + ":\r\n" +
" Original Source: " + e.OriginalSource;
lstEvents.Items.Add(message);
}
Result of click on the Button
: