Search code examples
c#wpfdrag-and-drop

Drag & Drop from explorer to wpf element


Everything seems to be simple and there are quite a few tutorials, but I cannot transfer data (in my case, an image) to a wpf window element. I was able to implement the transfer of an image from one element to another. But when I capture an image (for example, a desktop), when I transfer it to the desired element, the transfer option does not even appear, only a crossed-out circle and does not work out more than one event associated with drop (as if AllowDrop = false)

My code:

XAML

<Image x:Name="mainContent" Grid.Column="1" Stretch="Fill" AllowDrop="True" Drop="MainContent_Drop" />

C#

private void SpImageLeft_MouseDown(object sender, MouseButtonEventArgs e)
    {
        Image image = sender as Image;
        DragDrop.DoDragDrop(image, image, DragDropEffects.Copy);
    }

    private void MainContent_Drop(object sender, DragEventArgs e)
    {
        Image image = (Image)e.Data.GetData(typeof(Image));
        mainContent.Source = image.Source;
    }

I understand that when I take an image from explorer it will be different there, something like this, but it still does not even show that you can add an image

private void MainContent_Drop(object sender, DragEventArgs e)
    {
        string[] arr = (string[])e.Data.GetData(DataFormats.FileDrop);
        mainContent.Source = (ImageSource)new ImageSourceConverter().ConvertFromString(arr[0]);
    }

Solution

  • The following worked for me as a Drop event handler for an Image control:

    private void OnMainImageDrop(object sender, DragEventArgs e)
            {
                if (sender is Image image && e.Data.GetDataPresent(DataFormats.FileDrop))
                {
                    if (e.Data.GetData(DataFormats.FileDrop) is string[] filePaths)
                    {
                        image.Source.Freeze();
    
                        string filePath = filePaths[0];
    
                        var uriSource = new Uri(filePath);
                        var imageSource = new BitmapImage(uriSource);
    
                        image.Source = imageSource;
                    }
                }
                
            }
    

    I used a placeholder image to make sure the image had a size and served as a mouse hover surface.

    XAML:

    <Image x:Name="MainImage" Grid.Row="1" 
                   Source="Images/DotNetLogo.png" 
                   Stretch="Uniform" 
                   AllowDrop="True" Drop="OnMainImageDrop"/>