Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF Attached Events vs Non-Attached Events

The question is that after all my research I still can't find the difference between a regular routed event and a attached event. What is the functional the difference? or do others agree that there is none?

Implementation

The ButtonBase class declares a routed event named ClickEvent; a normal routed event.

public static readonly RoutedEvent ClickEvent = EventManager.RegisterRoutedEvent("Click", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(ButtonBase));  [Category("Behavior")] public event RoutedEventHandler Click {     add     {         base.AddHandler(ClickEvent, value);     }     remove     {         base.RemoveHandler(ClickEvent, value);     } } 

The Mouse class declares a routed event named MouseDownEvent; an attached event.

public static readonly RoutedEvent MouseDownEvent = EventManager.RegisterRoutedEvent("MouseDown", RoutingStrategy.Bubble, typeof(MouseButtonEventHandler), typeof(Mouse));  public static void AddMouseDownHandler(DependencyObject element, MouseButtonEventHandler handler) {     UIElement.AddHandler(element, MouseDownEvent, handler); }  public static void RemoveMouseDownHandler(DependencyObject element, MouseButtonEventHandler handler) {     UIElement.RemoveHandler(element, MouseDownEvent, handler); } 

Both events are registered with EventManager and stored as a public, static, readonly, fields in the same manner. ClickEvent has a backing CLR event field with custom add and remove accessors that call base.AddHandler and base.RemoveHandler respectively; both of which are declared in the UIElement base class that ButtonBase derives from. MouseDownEvent instead has two static methods AddMouseDownHandler and RemoveMouseDownHandler, that ultimately call the same two AddHandler and RemoveHandler methods declared in UIElement just like ClickEvent.

The Add*Handler and Remove*Handler static methods for actual attached events declared on a static class must follow a specific naming convention to allow the WPF event system to use reflection to find the appropriate add and remove handlers at run-time.


Usage

Both events can have handlers attached in XAML as follows:

<Grid Button.Click="Grid_Click"       Mouse.MouseDown="Grid_MouseDown"> </Grid> 

Both events can be attached in code as follows:

// Attach ClickEvent handler. myGrid.AddHandler(Button.ClickEvent, new RoutedEventHandler(Grid_Click));  // Attach MouseDownEvent handler. Mouse.AddMouseDownHandler(myGrid, Grid_MouseDown); 

As you can see both events can be attached to elements that do not own or declare them.


Conclusion - What is an Attached Event?

MSDN documentation states: http://msdn.microsoft.com/en-us/library/bb613550.aspx

Extensible Application Markup Language (XAML) defines a language component and type of event called an attached event. The concept of an attached event enables you to add a handler for a particular event to an arbitrary element rather than to an element that actually defines or inherits the event. In this case, neither the object potentially raising the event nor the destination handling instance defines or otherwise "owns" the event.

In addition, the official MCTS Training Kit for Exam 70-511 - Windows Applications Development with Microsoft .NET Framework 4 states:

It is possible for a control to define a handler for an event that the control cannot itself raise. These incidents are called attached events. For example, consider Button controls in a grid. The Button class defines a Click event, but the Grid class does not. However, you can still define a handler for buttons in the grid by attaching the Click event of the Button control in the XAML code.

The term "attached event" seems to be blurred throughout Microsoft learning resources, although it is clear there are two different, but very closely related concepts at play here: attached events and XAML attached event syntax. Both Microsoft sources I've quoted seem to be referring to XAML attached event syntax, rather than actual attached events. However, the attached events overview MSDN page does go on to show you how to implement an actual attached event, where as the training kit does not.

Mouse.MouseDownEvent is an example of a routed event declared on a static class with corresponding static add and remove handlers, otherwise known as an attached event. However, ButtonBase.ClickEvent is a normal routed event, although it can still be used with XAML attached event syntax in the same manner as an actual attached event.

The purpose of an actual attached event is that it allows developers to declare new routed events for existing UIElement-derived classes without having to subclass them; meaning you can just attach new routed events without them actually existing on the classes you want to raise or handle them on. But, wait a minute... isn't that the primary purpose of a pure routed event in the first place?

The routed events overview page on MSDN states: http://msdn.microsoft.com/en-us/library/ms742806.aspx

Functional definition: A routed event is a type of event that can invoke handlers on multiple listeners in an element tree, rather than just on the object that raised the event.

From that functional definition it seems that any routed event essentially provides the same exact functionality as an attached event. So basically an attached event is really just a means to declare a routed event on a static class and doesn't really offer any benefit over normal routed events.

Let me know you think, as I may be missing something here.

Thanks, Tim Valentine

like image 599
Tim Valentine Avatar asked Jun 01 '11 08:06

Tim Valentine


People also ask

What Attached events?

Attached events can be used to define a new routed event in a non-element class and raise that event on any element in your tree. To do so, you must register the attached event as a routed event and provide specific backing code that supports attached event functionality.

What are routed events in WPF?

A routed event is an event registered with the WPF event system, backed by an instance of the RoutedEvent class, and processed by the WPF event system. The RoutedEvent instance, obtained from registration, is typically stored as a public static readonly member of the class that registered it.

What is tunneling in WPF?

Tunnel Event In a WPF application, events are often implemented as a tunneling/bubbling pair. So, you'll have a preview MouseDown and then a MouseDown event. Given below is a simple example of a Routed event in which a button and three text blocks are created with some properties and events.


2 Answers

The difference is mostly syntactic, both delegate references are being handled by WPF's EventManager but what the attached events give you is the ability to declare generic functionality without needing to bloat all your classes' implementation.

In the case of a normal routed event, the class provides the interface to be able to at some point respond to an event by calling the event handler. But all WPF needs to know is if it is an object of derived from a given type and if a handler was registered. This means that we can make simpler class hierarchies and also supports the Open-Closed Principle (Open to Extension, Closed to Modification). This way a programmer can define a new behavior that several classes should have but does not need to modify the original classes.

See also Attached Properties

like image 189
K.Lawrence Avatar answered Sep 30 '22 09:09

K.Lawrence


Copying a comment to an answer so that it won't eventually get lost:

An Attached Event is an event that can be attached to any object, not just the object that defines the event.

A Routed event is an event that can be routed to handlers not part of the object.

It is possible for an event to be both a Routed Event and Attached Event. For example, Button.Click is an attached event because you can attach that event to objects other than the Button object. Its also a Routed Event because it can be handled by multiple Button.Click event handlers in the UI tree unless you stop this behavior, such as marking the event as handled in one of the handlers.

(by Rachel Nov 8 '12 at 20:39)

like image 24
StayOnTarget Avatar answered Sep 30 '22 09:09

StayOnTarget