** updated this post for Blend 3 RC release
In my previous post, I talked about adding Drag and Drop functionality into controls that implement ItemsControl via a Decorator pattern. In that DragDrop Decorator, I have created a Drag Adorner to create a visual effect of the actual item you are dragging. In this post I have added a new functionality where you can see an Insert Adorner that shows you the position you are attempting to add the item to. Since a picture tells a thousand words….
With the release of a new feature called Behaviors seen in Mix 09, I have ported over my code into a Behavior. To create a behavior, you need to subclass the Behavior or Behavior<T> class in the Microsoft.Expression.Interactivity namespace. You can find this DLL when you install Expression Blend 3 in C:\Program Files\Microsoft Expression\Blend 3 Preview\Libraries\WPF folder.
When you subclass, you can override the OnAttached method to initialize your behavior, and you can access the control you added the behavior to via the this.AssoicatedObject. If you subclassed using the generic Behavior<T>, the AssociatedObject property will be returned to you of Type T, very nice! This is a cut down version of my subclassed behavior, just for illustration.
public class ItemsControlDragDropBehavior : Behavior<ItemsControl>
{
protected override void OnAttached()
{
this.AssociatedObject.AllowDrop = true;
this.AssociatedObject.PreviewMouseLeftButtonDown +=
new MouseButtonEventHandler(itemsControl_PreviewMouseLeftButtonDown);
this.AssociatedObject.PreviewMouseMove +=
new MouseEventHandler(itemsControl_PreviewMouseMove);
this.AssociatedObject.PreviewMouseLeftButtonUp +=
new MouseButtonEventHandler(itemsControl_PreviewMouseLeftButtonUp);
this.AssociatedObject.PreviewDrop += new DragEventHandler(itemsControl_PreviewDrop);
this.AssociatedObject.PreviewQueryContinueDrag +=
new QueryContinueDragEventHandler(itemsControl_PreviewQueryContinueDrag);
this.AssociatedObject.PreviewDragEnter +=
new DragEventHandler(itemsControl_PreviewDragEnter);
this.AssociatedObject.PreviewDragOver +=
new DragEventHandler(itemsControl_PreviewDragOver);
this.AssociatedObject.DragLeave += new DragEventHandler(itemsControl_DragLeave);
}
// more code here....
}
In Xaml, you ‘add’ a behavior like so.
<ListView Margin="10" ItemTemplate="{StaticResource listViewItemTemplate}">
<Interaction:Interaction.Behaviors>
<DragDrop:ItemsControlDragDropBehavior ItemType="{x:Type this:Product}"
DataTemplate="{StaticResource listViewItemTemplate}" />
</Interaction:Interaction.Behaviors>
</ListView>
The behavior expects the Type of item you are going to be using for your ItemsControl via the ItemType property, which can be a business object, or a primitive type. This is used to ensure that the ItemsControl only accept a DragDrop of the right type. The behavior also expects you to define a DataTemplate, and this data template is being used by the Drag Adorner to render the appropriate ‘look’. This is an added flexibility which allows you to define a data template that is different from the data template you used in your ItemsControl’s ItemTemplate.
I won’t be going through the code of the Drag and Insert Adorners, do download the code to have a look. Also feel free to create your own custom Drag and Insert Adorners. If you want the ability to use different Adorners at runtime, you can create an Interface for each and perhaps use a Factory pattern or Dependency Injection to instantiate different Adorners. If you need suggestions or assistance to implement this, leave a comment or send me an email, I’ll be happy to help.
To get a copy of the code for this behavior, go to my contribution page at Expression Gallery. (updated this sample to work with Blend 3 RC)
Alternatively, you can download the Decorator version of this sample.
| Share this post: |





July 1, 2009 at 11:01 am
[...] WPF: ItemsControl Drag Drop Behavior [...]
July 7, 2009 at 9:47 am
[...] WPF: ItemsControl Drag Drop Behavior [...]
July 7, 2009 at 9:49 am
[...] WPF: ItemsControl Drag Drop Behavior [...]