Today, I decided to start a series that I’m calling “Thinking in WPF”. As you already know, I do NOT consider myself as a WPF specialist, so those blog posts don’t aim at giving a perfect knowledge of the “best” (if there are any) ways of thinking in WPF. I’d just like to share what I’m experiencing 🙂
In my previous post, I started to write about things that I think makes WPF different. In the current project I’m working on at work, I had a good example of a new way of thinking with WPF. Todays article deals with a new WPF concept called Attached properties.
Imagine you need to display a list of person (that’s very original isn’t it ?). Each person has a name, a first name, and let’s say an address. Because you want to display a list of data, you’re probably going to use a ListView.You also would like to let the user sort this list of data in the order he wants, simply by dragging and dropping items in the control.
This is a feature that is possible to implement for a ListView (by handling common Drag’n’Drop events such as DragEnter, DragOver, PreviewDrop… Basically, you can think of two ways to implement this behavior:
- 1. handle all Drag’n’Drop events in the code behind (C# file)
- 2. inherit ListView and add new features
Well, in my opinion, none of those two options are very elegant:
- The first one pollutes the code behind file with “functional” code. I prefer trying to keep the code behind file as clean as possible. Moreover, this solution doesn’t allow ANY reuse.
- The second one is maybe the first one we can think about, but… It forces to change all the ListView control to our NewListView control (which inherit ListView). I don’t like that solution that much.
What is an Attached property ?
The good news is that WPF allows you to implement this by using an alternative, an Attached property. Let’s first have a look at the definition from MSDN website:
“An attached property is a concept defined by Extensible Application Markup Language (XAML). An attached property is intended to be used as a type of global property that is settable on any object.”
Hmmm… What does that mean ? Actually, if you already played with WPF, you already encountered a lot of attached properties. For example if you add an Image in a DockPanel, you might write something like
<Image DockPanel.Dock=”Top” …/>
Have you ever thought about the DockPanel.Dock part ? It is funny because Image objects don’t have a DockPanel property. Actually all UI element that you can dock (Image, TextBlock, anything) doesn’t have a DockPanel property, so how it is possible to write that ? It is possible because the DockPanel control defines an attached property.
Attached properties as an extensibility mechanism: the Attached Behavior pattern
As the name suggests, an attached property can be attached to arbitrary object. In the previous example (with DockPanel.Dock) we use an attached property to add an attribute to an object (we add the information “I want to dock this image on the top“). What is important, is that we can also use attached properties to provide extensibility without the need for traditional inheritance.
A very nice definition of the Attached Behavior can be found on the blog of John Gossman:
“The Attached Behavior pattern encapsulates “behavior” (usually user interactivity) into a class outside the visual heirarchy and allows it to be applied to a visual element by setting an attached property and hooking various events on the visual element.”
How does that work ? Basically what we can do is the following:
- Declare a boolean attached property in a new class, for example DragDropHelper.cs
- When the value of this attached property, it is possible to hook the interesting events (OnDrag, OnDrop…) and implement Drag’n’Drop operation in them
I suggest you to have a look at this excellent post from Beatriz Costa which implement Drag’n’Drop using attached properties.
The benefits of this technique are the following:
- No need to change all your ListView control to a subclass that you would create by using standard inheritance principle
- It becomes possible (as in Beatriz Costa post) to implement the Drag’n’Drop behaviour on the mode generic ItemsControl class
There are plenty of things that can be achieved using attached properties. In this post, I talked about implementing Drag’n’Drop using an attached property, but a lot of things that could be done using inheritance can be done using attached properties.