Reputation: 2110
On my way to understanding WPF RoutedEvent
handling, is this the way it works?
Say I have a Window
with a Grid
and a Button
inside the Grid
. My Button_Click
event handler looks like this:
private void Button_Click(object sender, RoutedEventArgs e)
{
// Do stuff
e.Handled = true;
}
Calling e.Handled = true;
stops the event bubbling up the visual tree.
This is where I'm beginning to get lost.
e.Handled = True;
could result in another event handler firing in the Grid
or the Window
if they had an event listener for Click
active?Upvotes: 2
Views: 1182
Reputation: 22089
Calling
e.Handled = True;
stops the event bubbling up the visual tree.
No, it does not. It only indicates to subsequent event handlers on the route up the element tree that another event handler before has marked the event as handled.
If I understand correctly, not calling
e.Handled = True;
could result in another event handler firing in theGrid
or theWindow
if they had an event listener forClick
active?
Yes, but it depends. In some cases, controls will mark an event automatically as handeled, e.g. Button
, so in these cases event if other elements had handlers for such an event attached, they would not have been executed.
The
ButtonBase
marks theMouseLeftButtonDown
event as handled in theOnMouseLeftButtonDown
method and raises theClick
event. Hence, theOnMouseLeftButtonDown
event will never occur for a control that inherits fromButtonBase
.
Moreover, in XAML, if you add an event handler, it will only be executed if the event is not handled, yet. However, in code-behind, you can still add an event handler that is executed even if e.Handled
is true
using the AddHandler
method on UIElement
s and passing true
to the handledEventsToo
argument.
public void AddHandler (System.Windows.RoutedEvent routedEvent, Delegate handler, bool handledEventsToo);
Adds a routed event handler for a specified routed event, adding the handler to the handler collection on the current element. Specify
handledEventsToo
astrue
to have the provided handler be invoked for routed event that had already been marked as handled by another element along the event route.
As said before, this is only possible in code-behind, there is no XAML syntax for it.
Is there a point where the bubbling stops by itself?
Yes, it stops at the root of the element tree, in the majority of cases e.g. a Window
.
Is there a performance effect if I don't stop the event propagation?
The event will still be propagated, that is how the routed event mechanism works. Of course, if other handlers are not invoked because the event is marked as handled, those lines are not executed, but that changes the functionality of your application, which is a different story. As a general rule, do not optimze prematurely. If there is a preformance issue anytime, then use a profiler to analyze your application, get reliable and meanigful data to find the hotspots and solve the issue there. There is no need or benefit in optimizing something beforehand that will not likely be a performance concern.
And the most important, should I, by default, mark the event handled?
Again it depends on what you want to achieve. Suppose you have a ListView
with lots of items. It shows a scrollbar that can be operated using the mouse wheel. So when you start to scroll the mouse wheel, an event is raised that invokes scrolling the embedded ScrollViewer
. In this case, the event is handled automatically. Why? If this ListView
was part of a large UI Control with other parent ScrollViewer
s they would scroll, too, if the event was not handled. Imagine multiple nested controls scrolling all at once, that would be terrible. In other scenarios there may be a need that parent controls also get the event.
This is an excerpt from the documentation on When to Mark Events as Handled:
There is no absolute rule for when you should mark routed events as handled, either as an application author, or as a control author who responds to existing routed events or implements new routed events. For the most part, the concept of "handled" as carried in the routed event's event data should be used as a limited protocol for your own application's responses to the various routed events exposed in WPF APIs as well as for any custom routed events. Another way to consider the "handled" issue is that you should generally mark a routed event handled if your code responded to the routed event in a significant and relatively complete way.
The full paragraph gives you a more detailed idea of what a significant and complete way is, but as you can see, there is no golden rule that you can apply, it dependes on your requirements and design.
Upvotes: 3