Drag and drop files into your WPF application with MVVM

Sep 14, 2014

Drag and drop and one of the UI interaction every user loves to have. I gave it a whip in something I was playing with at home.

There might be better ways to bring Drag N' Drop interaction in WPF application but I choose to use GongSolution for WPF Drag Drop

One reason for using this library for drag and drop interaction is that the library supports MVVM way to do it and does not require much integration to get started.

You can add Gong WPF DragDrop library from Nuget into your MVVM enabled WPF application.

Add enable a UI element for drag - drop support add following properties to it:

DragDrop.IsDropTarget="True" and DragDrop.DropHandler="{Binding}"

Here is how my sample XAML file looks like after adding above mentioned properties.

<Window x:Class="GongDragAndDropSample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:dragDrop="clr-namespace:GongSolutions.Wpf.DragDrop;assembly=GongSolutions.Wpf.DragDrop"
        Title="MainWindow">
    <Window.DataContext>
        <Binding Path="Main"
                 Source="{StaticResource Locator}" />
    </Window.DataContext>
    <Border dragDrop:DragDrop.IsDropTarget="True"
            dragDrop:DragDrop.DropHandler="{Binding}"
            BorderThickness="4,4,4,0"
            Background="#DDDDDD"
            CornerRadius="40">
        <Grid>
        </Grid>
    </Border>
</Window>

Next your ViewModel should explicitly implement IDropTarget

It provides IDropInfo instance with the information regarding files / object that are being dragged on the UI element or dropped onto it.

Here is what my ViewModel looks like after implementing the IDropTarget interface and handling file type drag - drop items.

public class MainViewModel : ViewModelBase, IDropTarget
{
    void IDropTarget.DragOver(IDropInfo dropInfo)
    {
        var dragFileList = ((DataObject)dropInfo.Data).GetFileDropList().Cast<string>();
        dropInfo.Effects = dragFileList.Any(item =>
        {
            var extension = Path.GetExtension(item);
            return extension != null && extension.Equals(".zip");
        }) ? DragDropEffects.Copy : DragDropEffects.None;
    }

    void IDropTarget.Drop(IDropInfo dropInfo)
    {
        var dragFileList = ((DataObject)dropInfo.Data).GetFileDropList().Cast<string>();
        dropInfo.Effects = dragFileList.Any(item =>
        {
            var extension = Path.GetExtension(item);
            return extension != null && extension.Equals(".zip");
        }) ? DragDropEffects.Copy : DragDropEffects.None;
    }
}

In this particular code I am trying to handle file types with extension .zip.

Notice the use of DragDropEffects used to accept or reject drag - drop on the UI element.

I BINGED to find straight forward way to do Drag-Drop for files into application but could not find it. Most of the examples out there are either for same application drag - drop or are too old to work.

Happy coding !!