Recently I had an article published on DevX about how to implement a robust and reusable drag drop behavior in Silverlight 2. The implementation relied heavily on attached behaviors, a pattern that I have used frequently in my work with WPF and Silverlight. The Expression team seems to share my positive sentiment around this pattern and have written a library for Silverlight 3 (System.Interactivity) and added tool support for it in Blend 3.
I decided that it was time that I explore how to re-implement my drag drop behavior using System.Interactivity and I found it to be a painless transition that leads to a more elegant solution in my opinion. There were some refactoring patterns that came out of this effort:
- Attached properties used to set an attached behavior become dependency properties on the behavior class itself if you want to set them in XAML.
- Attached properties used for state management in an attached behavior become properties on the behavior class itself.
- All event handlers for attached behaviors no longer have to be static methods.
In addition to those points, I’m curious how one would implement a behavior that multi-targets certain types that may be disjoint in the inheritance hierarchy (i.e. may not have the same base class). An example is a behavior changes the background property of an element. FrameworkElement does not have a background property, but several of its children do (such as Border and Button). One solution I’ve thought of is to target the highest element in the hierarchy and have a dictionary of valid types that you can attempt to cast when the behavior is attached. Seems like wasted effort and doesn’t give the best Blend experience for the designer. Just something to think about I suppose.
The code is posted at GitHub.