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

    Published by on June 5th, 2009 5:15 pm under Composite Application Guidance for WPF & SL, p&p, Patterns & Practices, Prism-v2, Windows Presentation Foundation, WPF

    5 Comments

    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 :) !!!

     kick it on DotNetKicks.com

    Shout it

    Tags: , , , , ,

    • JamesS

      Hi Damian,

      How would you achieve the drap and drop on the viewmodel if you were using an interface to the view for example like this…

      Because the interface itself does not derive from UserControl and in your example you inject in the view itself.

      public PositionsViewModel(IPositionsView view, IPositionsService service, IViewDragManager dragManager)
      {
      this.View = view;
      this.Service = service;
      viewDragManager = dragManager;
      viewDragManager.AddDraggableView(this.View, this.View.dragger);
      this._positionItems = service.GetPositions();
      this.View.Model = this;
      }

Archives

Categories