Faites glisser et déposez des fichiers dans WPF

106

J'ai besoin de déposer un fichier image dans mon application WPF. Un événement se déclenche actuellement lorsque je dépose les fichiers, mais je ne sais pas quoi faire ensuite. Comment obtenir l'image? L' senderobjet est-il l'image ou le contrôle?

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?
}
Eamonn McEvoy
la source

Réponses:

211

C'est essentiellement ce que vous voulez faire.

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]);
  }
}

N'oubliez pas non plus de connecter l'événement en XAML, ainsi que de définir l' AllowDropattribut.

<StackPanel Name="ImagePanel" Drop="ImagePanel_Drop" AllowDrop="true">
    ...
</StackPanel>
AR
la source
génial fonctionne un charme, juste échangé "HandleFileOpen (fichiers [0]);" à "foreach (fichier de chaîne dans les fichiers) {Openfile (fichier);}" - Merci :)
Eamonn McEvoy
1
Désolé :) Je veux dire que le glisser-déposer ne fonctionne pas. AllowDropest défini sur True mais le Dropgestionnaire d'événements n'est jamais appelé. Lorsque je fais glisser un fichier sur la fenêtre, je vois un symbole circulaire «refusé»
mcont
4
J'ai utilisé un Gridélément racine, avec un Borderintérieur avec la Backgroundpropriété définie sur quelque chose (le blanc est bien, mais pas transparent). Dans le Borderje mets le contenu réel.
mcont
1
Définir l'arrière-plan sur transparent a bien fonctionné pour moi lorsque j'ai essayé de déposer sur une grille. Apparemment, vous avez besoin d'un arrière-plan pour que le test de réussite ait lieu. Merci à cette entrée de blog: codeinreview.com/136/enabling-drag-and-drop-over-a-grid-in-wpf
DustinA
1
Un vrai Gotcha est que si vous exécutez VisualStudio en tant qu'administrateur - déboguez votre application - et faites glisser depuis FileExplorer en tant que non administrateur, le contexte de sécurité est différent et aucun événement de glisser ne se déclenchera. M'a coûté 30 minutes de vie.
Hans Karlsen
35

Le fichier image est contenu dans le eparamètre, qui est une instance de la DragEventArgsclasse .
(Le senderparamètre contient une référence à l'objet qui a déclenché l'événement.)

Plus précisément, vérifiez le e.Datamembre ; comme l'explique la documentation, cela renvoie une référence à l'objet de données ( IDataObject) qui contient les données de l'événement glisser.

L' IDataObjectinterface fournit un certain nombre de méthodes pour récupérer l'objet de données que vous recherchez. Vous voudrez probablement commencer par appeler la GetFormatsméthode afin de connaître le format des données avec lesquelles vous travaillez. (Par exemple, est-ce une image réelle ou simplement le chemin vers un fichier image?)

Ensuite, une fois que vous avez identifié le format du fichier glissé, vous appellerez l'une des surcharges spécifiques de la GetDataméthode pour récupérer réellement l'objet de données dans un format particulier.

Cody Gray
la source
12

De plus, pour répondre à AR, veuillez noter que si vous souhaitez utiliser TextBoxpour abandonner, vous devez savoir ce qui suit.

TextBoxsemble avoir déjà une gestion par défaut pour DragAndDrop. Si votre objet de données est un String, cela fonctionne simplement. Les autres types ne sont pas gérés et vous obtenez l' effet de souris Interdit et votre gestionnaire Drop n'est jamais appelé.

Il semble que vous puissiez activer votre propre gestion avec e.Handledsur true dans un PreviewDragOvergestionnaire d'événements.

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);  
     }
}
Développeur
la source
1
L'exemple d'AR manque le gestionnaire PreviewDragOver, ce qui est un peu important pour que tout se réunisse. Gloire.
Greg Vogel