A colleague of mine was having a bit of trouble getting drag and drop working in a way that fitted well with the MVVM pattern. This is really quite simple once you have a certain level of understanding of Patterns, but is a complete nightmare if you do not.
One of the founding principals of MVVM is that you should never be writing code in your code behind, it should all be encapsulated away and be bindable in XAML to achieve the result. Anyone who has tackled drag and drip will have suddenly found their code behind covered in code for handling both the drag and the drop, and multiplied up when dealing with multiple controls.
I cruised the web for information, of which I found plenty and settled on an example by Bea Stollnitz of Microsoft. In her post i had found one of the best and most intuitive examples of the Drag & Drop Behaviour written in C#.
I am not going to go into all of her code which she has available for download, just to say that it is nice, and is exactly what I am looking for even with the limitations that she described.
The functionality available allows you to drag a piece of data from one ItemsControl to another of the same data type or to reorder within itself. It provides for a floating template for the dragging item and a visual cue for the drop location.

I wanted to augment this to allow for other scenarios while keeping as much functionality as possible.
Likes:
- Drag functionality
- Drag templating – nice!
- Encapsulation of logic
Dislikes:
- No way to control drop behaviour
My version lets you inject additional functionality at runtime. The adjusted class diagram shows the relationships, but we only really use the DragDropBehaviour class
You can still use the standard options:
<DockPanel>
<Label DockPanel.Dock="Top" Content="Checkout" />
<ListBox hlb:DragDropBehaviour.IsDragSource="true"
hlb:DragDropBehaviour.IsDropTarget="true"
hlb:DragDropBehaviour.DragTemplate="{StaticResource MyTemplate}"
ItemsSource="{Binding Items}"
MinWidth="100"
MinHeight="100"
AllowDrop="True"
SelectionMode="Multiple">
</ListBox>
</DockPanel>
But I have added another bindable option of DropProcessor that allows you to override the default DropProcessor to achieve whatever you want.
<ListBox hlb:DragDropBehaviour.DropProcessor="{Binding DropProcessor}"
hlb:DragDropBehaviour.IsDragSource="true"
hlb:DragDropBehaviour.IsDropTarget="true"
hlb:DragDropBehaviour.DragTemplate="{StaticResource moo}"
ItemsSource="{Binding Items}"
MinWidth="100"
MinHeight="100">
In this example I have created a little gun shop called “Nutters R’ Us” where you can buy weapons and ordinance. You can see that there is an area for weapons, and area for ordinance and an area for your selected purchases.

I have added a custom DropProcessor only to the Checkout area that only applies when you drop items of type “OrdinanceViewModel”
Public Class CheckoutDropProcessor
Inherits DropProcessor
Public Overrides Function GetDropAdorner(ByVal behaviour As DragDropBehaviour, ByVal adornerLayer As System.Windows.Documents.AdornerLayer) As DropAdorner
If TypeOf behaviour.TargetItemContainer.DataContext Is WeaponViewModel Then
If TypeOf behaviour.SourceItemContainer.DataContext Is OrdnanceViewModel Then
Return New OrdnanceToWeaponDropAdorner(behaviour, adornerLayer)
End If
End If
Return MyBase.GetDropAdorner(behaviour, adornerLayer)
End Function
Public Overrides Function IsDropAllowed(ByVal behaviour As DragDropBehaviour, ByVal draggedItem As Object) As Boolean
If Not behaviour.SourceItemContainer Is Nothing AndAlso TypeOf behaviour.SourceItemContainer.DataContext Is OrdnanceViewModel Then
If Not behaviour.TargetItemContainer Is Nothing AndAlso TypeOf behaviour.TargetItemContainer.DataContext Is WeaponViewModel Then
Return True
End If
Return False
End If
Return MyBase.IsDropAllowed(behaviour, draggedItem)
End Function
Public Overrides Sub Drop(ByVal behaviour As DragDropBehaviour, ByVal draggedItem As Object, ByVal dropEffect As System.Windows.DragDropEffects)
If Not behaviour.TargetItemContainer Is Nothing AndAlso TypeOf behaviour.TargetItemContainer.DataContext Is WeaponViewModel Then
If TypeOf behaviour.SourceItemContainer.DataContext Is OrdnanceViewModel Then
CType(behaviour.TargetItemContainer.DataContext, WeaponViewModel).AddOrdinance(CType(behaviour.SourceItemContainer.DataContext, OrdnanceViewModel))
Dim indexRemoved As Integer = -1
If ((dropEffect And DragDropEffects.Move) <> DragDropEffects.None) Then
indexRemoved = Utilities.RemoveItemFromItemsControl(behaviour.SourceItemsControl, draggedItem)
End If
If (((indexRemoved <> -1) AndAlso (behaviour.SourceItemsControl Is behaviour.TargetItemsControl)) AndAlso (indexRemoved < behaviour.InsertionIndex)) Then
behaviour.InsertionIndex -= 1
End If
Exit Sub
End If
End If
MyBase.Drop(behaviour, draggedItem, dropEffect)
End Sub
End Class

This class inherits from the base class “DropProcessor” that provides the same functionality as the original article, but I have
overridden couple of methods. The first, “GetDropAdorner” test to make sure that you are dropping a OrdinanceViewModel onto a WeaponViewModel and provides a different and custom DropAdorner that instead of providing the lovely insertion visual it just applied a “IsDropTarget” property to the ListBoxItem to allow a template to control the visual. The IsAllowedDrop also test for this case, as does the Drop method. In all cases they are just testing for a special case of Drop and call the base classes methods.
The diagram for the demo app is a little large, but you can see how much I still suck at MVVM, and although I have learned a lot doing this demo, I am still tempted to share ViewModels… but that is a bad habit.

I have highlighted the two main classes, and we have already discussed the CheckoutDropProcessor. This allows you the flexibility to augment your drop scenarios without all of your developers having to get too deep in the guts on the behaviour, thus leaving them plenty of time for the real work of actually building something useful.
I have put this up on Codeplex , and both the source and binaries are available.
Technorati Tags: .NET WPF CodeProject MVVM Silverlight
Smart Classifications
Each classification [Concepts, Categories, & Tags] was assigned using AI-powered semantic analysis and scored across relevance, depth, and alignment. Final decisions? Still human. Always traceable. Hover to see how it applies.
What to read next
Advice on using XamRibbon with Composite WPF
Provides guidance and code examples for integrating Infragistics XamRibbon with Composite WPF, including custom region adapters for dynamic …
Creating a WPF Work Item Control
Learn how to build a custom WPF work item control for Visual Studio Team System, enabling WPF UI integration in work item forms using a …
Wpf Ninject Dojo: The Data Provider
Explains how to use a custom NinjectDataProvider in WPF to enable dependency injection for ViewModels, improving flexibility and design-time …
MVVM for Dummies
Explains the MVVM pattern in WPF and Silverlight, highlighting separation of concerns, code structure, and the roles of commanding, …
The Evolution of My Journey with Azure DevOps: Lessons and Insights
Personal experiences and lessons on using Azure DevOps, covering its evolution, migration strategies, custom tools, and practical advice for …
Detecting agile theatre with real delivery signals
Why Most Companies Operating Models Fail in Dynamic Markets
A concise comparison of Predictive and Adaptive Operating Models, explaining why traditional structures fail in dynamic markets and how …
Don’t Manage Dependencies, Remove Them
Explains why dependencies are a sign of poor system design and outlines steps to eliminate them by aligning teams, clarifying ownership, and …
The Estimation Trap: How Tracking Accuracy Undermines Trust, Flow, and Value in Software Delivery
Tracking estimation accuracy in software delivery leads to mistrust, fear, and distorted behaviours. Focus on customer value, flow, and …
Flow of Value vs Flow of Work – Misnomer or Useful Shorthand?
Compares “flow of value” and “flow of work” in Kanban, explaining why only validated outcomes count as value and stressing the need for …
Why Outsourcing DevOps Fails, and How Real Engineering Excellence Starts With Your Team
Avoid DevOps vendor lock-in, discover how true engineering excellence starts with partnership, not outsourcing. Ready to transform your …
Detecting agile theatre with real delivery signals
Don’t Manage Dependencies, Remove Them
Explains why dependencies are a sign of poor system design and outlines steps to eliminate them by aligning teams, clarifying ownership, and …
The Estimation Trap: How Tracking Accuracy Undermines Trust, Flow, and Value in Software Delivery
Tracking estimation accuracy in software delivery leads to mistrust, fear, and distorted behaviours. Focus on customer value, flow, and …
Flow of Value vs Flow of Work – Misnomer or Useful Shorthand?
Compares “flow of value” and “flow of work” in Kanban, explaining why only validated outcomes count as value and stressing the need for …
Why Outsourcing DevOps Fails, and How Real Engineering Excellence Starts With Your Team
Avoid DevOps vendor lock-in, discover how true engineering excellence starts with partnership, not outsourcing. Ready to transform your …
Estimating Better in an Overloaded System Is a Poor Man’s Strategy
High work in progress (WIP) causes delays and unpredictability; improving estimates won’t help. Limiting WIP and focusing on flow is key to …