135

I need to drop an image file into my WPF application. I currently have a event firing when I drop the files in, but I don't know how what to do next. How do I get the Image? Is the sender object the image or the control?

private void ImagePanel_Drop(object sender, DragEventArgs e)
{
    //what next, dont know how to get the image object, can I get the file path here?
}
Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
Eamonn McEvoy
  • 8,876
  • 14
  • 53
  • 83

3 Answers3

258

This is basically what you want to do.

private void ImagePanel_Drop(object sender, DragEventArgs e)
{

  if (e.Data.GetDataPresent(DataFormats.FileDrop))
  {
    // Note that you can have more than one file.
    string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);

    // Assuming you have one file that you care about, pass it off to whatever
    // handling code you have defined.
    HandleFileOpen(files[0]);
  }
}

Also, don't forget to actually hook up the event in XAML, as well as setting the AllowDrop attribute.

<StackPanel Name="ImagePanel" Drop="ImagePanel_Drop" AllowDrop="true">
    ...
</StackPanel>
viggity
  • 15,039
  • 7
  • 88
  • 96
A.R.
  • 15,405
  • 19
  • 77
  • 123
  • awesome works a charm, just swapped "HandleFileOpen(files[0]);" to "foreach(string file in files) { Openfile(file); }" - Thanks :) – Eamonn McEvoy Apr 14 '11 at 13:36
  • @Matteo Care to elaborate? – A.R. Dec 30 '14 at 16:27
  • 4
    Sorry :) I mean the drag & drop doesn't work. ­`AllowDrop` is set to True but the `Drop` event handler is never called. When I drag a file over the window, I see a "denied" circular symbol – mcont Dec 30 '14 at 16:30
  • @Matteo I'm having the save problem. How exactly did you fix this? – jbriggs Jan 27 '15 at 18:02
  • 7
    I used a `Grid` as root element, with a `Border` inside with the `Background` property set to something (white is fine, but not transparent). Inside the `Border` I put the actual content. – mcont Jan 27 '15 at 19:39
  • 5
    Setting the background to transparent worked fine for me when trying to drop onto a Grid. Apparently you need a background so the hit test happens. Thanks to this blog entry: http://codeinreview.com/136/enabling-drag-and-drop-over-a-grid-in-wpf/ – DustinA Dec 10 '16 at 02:40
  • 16
    One real Gotcha is that if you run VisualStudio as Admin - debug your app - and drag from FileExplorer as non admin the security context is different and no drag events will trigger. Costed me 30 minutes of life. – Hans Karlsen Mar 11 '20 at 14:25
36

The image file is contained in the e parameter, which is an instance of the DragEventArgs class.
(The sender parameter contains a reference to the object that raised the event.)

Specifically, check the e.Data member; as the documentation explains, this returns a reference to the data object (IDataObject) that contains the data from the drag event.

The IDataObject interface provides a number of methods for retrieving the data object that you're after. You'll probably want to start by calling the GetFormats method in order to find out the format of the data that you're working with. (For example, is it an actual image or simply the path to an image file?)

Then, once you've identified the format of the file being dragged in, you'll call one of the specific overloads of the GetData method to actually retrieve the data object in a particular format.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
23

Additionally to answer of A.R. please note that if you want to use TextBox to drop you have to know following stuff.

TextBox seems to have already some default handling for DragAndDrop. If your data object is a String, it simply works. Other types are not handled and you get the Forbidden mouse effect and your Drop handler is never called.

It seems like you can enable your own handling with e.Handled to true in a PreviewDragOver event handler.

XAML

<TextBox AllowDrop="True"    x:Name="RtbInputFile"      HorizontalAlignment="Stretch"   HorizontalScrollBarVisibility="Visible"  VerticalScrollBarVisibility="Visible" />

C#

RtbInputFile.Drop += RtbInputFile_Drop;            
RtbInputFile.PreviewDragOver += RtbInputFile_PreviewDragOver;

private void RtbInputFile_PreviewDragOver(object sender, DragEventArgs e)
{
    e.Handled = true;
}

private void RtbInputFile_Drop(object sender, DragEventArgs e)
{
     if (e.Data.GetDataPresent(DataFormats.FileDrop))
     {
                // Note that you can have more than one file.
                string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
                var file = files[0];                
                HandleFile(file);  
     }
}
NoWar
  • 36,338
  • 80
  • 323
  • 498
  • 2
    A.R.'s example misses the PreviewDragOver handler, which is kinda important to make it all come together. Kudos. – Greg Vogel Feb 04 '17 at 02:13