How to: Drag and Drop WPF Views between Regions in Prism-v2

Yesterday, this question in the Prism forums at codeplex, had us (p&p Sustained Engineering Team) thinking about a possible way to implement drag and drop of views from one region to another. Since we had not seen any samples on how that could be done, I decided to implement one. Thanks to Ezequiel Jadib, who helped me with his experience using WPF and Silverlight drag and drop.

Update 2009/06/26: I created a post that provides Drag and Drop functionality for Prism and Silverlight.

This blog post will explain the process to enable Drag and Drop for your views (assuming they are not in scoped regions), and provide a sample based on the Hello World Quickstart from Prism-v2.

Some more information about WPF Drag and Drop can be found here:

Creating the ViewDragManager

After a couple of quick spikes, with Julian "Attached Behavior" Dominguez and Matias Bonaventura, we arrived to the conclusion that having a single component to manage the drag and drop of views would be the best option. This component was called ViewDragManager.

To use the ViewDragManager in your solution you will need to follow these steps:

  1. Register the ViewDragManager in your application's container. You can override the ConfigureContainer method of the UnityBootstrapper to do this. It should be registered as a Singleton since it will act as a service:
    protected override void ConfigureContainer()
           {
               base.ConfigureContainer();
               RegisterTypeIfMissing(typeof(IViewDragManager), typeof(ViewDragManager), true);
           }

  2. Add a reference to the DragDropManager assembly in your Shell project, and to the modules that will enable draggable views.
  3. Add a namespace reference in your Shell to be able to access the ViewDragManager:
    xmlns:DragDrop="clr-namespace:DragDropManager;assembly=DragDropManager"

  4. Set the ViewDragManager.AllowDrop dependency property in each of the regions that will enable views to be dragged into them to True.
    <ContentControl DragDrop:ViewDragManager.AllowDrop="True"
                        Height="200" Name="DropRegion" cal:RegionManager.RegionName="DropRegion" />

  5. Create a Thumb in each of the views you want to be able to Drag and Drop.
    <Thumb Background="DarkSlateGray" Width="10" Height="60" x:Name="dragger"/>

  6. Call the AddDraggableView method of the ViewDragManager passing the view and its thumb as parameters. A possible place to do this could be the View's Presenter constructor:
    public DraggableViewPresenter(DraggableView view,
               IRegionManager manager, IViewDragManager dragManager)
           {
               this.viewDragManager = dragManager;
               this.regionManager = manager;
               this.View = view;
               viewDragManager.AddDraggableView(this.View, this.View.dragger);
           }

That's all, you should now be able to drag your views between the regions you enabled :)

Outcome

The outcome is the following (clicking the image will probably provide a better view).

Drag and Drop Sample

Disclaimer

This code is provided “AS IS” with no warranties, and confers no rights.

Download

You can get the sample from here: DragDropSample.zip.

Note: The code to create the ViewAdorner was taken from this sample.

I hope this is useful, and greatly appreciate your feedback to continue improving.

Have fun dragging :) !!!