Ziehen Sie Dateien per Drag & Drop in WPF

106

Ich muss eine Bilddatei in meiner WPF-Anwendung ablegen. Ich habe derzeit ein Ereignis ausgelöst, wenn ich die Dateien ablege, aber ich weiß nicht, wie ich als nächstes vorgehen soll. Wie bekomme ich das Bild? Ist das senderObjekt das Bild oder das Steuerelement?

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
quelle

Antworten:

211

Dies ist im Grunde das, was Sie tun möchten.

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

Vergessen Sie auch nicht, das Ereignis in XAML zu verknüpfen und das AllowDropAttribut festzulegen.

<StackPanel Name="ImagePanel" Drop="ImagePanel_Drop" AllowDrop="true">
    ...
</StackPanel>
AR
quelle
genial funktioniert ein Zauber, nur "HandleFileOpen (files [0])" getauscht; zu "foreach (String-Datei in Dateien) {Openfile (Datei);}" - Danke :)
Eamonn McEvoy
@Matteo Möchtest du das näher erläutern?
AR
1
Entschuldigung :) Ich meine, das Drag & Drop funktioniert nicht. AllowDropist auf True gesetzt, aber der DropEreignishandler wird nie aufgerufen. Wenn ich eine Datei über das Fenster
ziehe
4
Ich habe ein Gridals Root-Element verwendet, mit einem BorderInside, dessen BackgroundEigenschaft auf etwas festgelegt ist (Weiß ist in Ordnung, aber nicht transparent). In die Borderstelle ich den eigentlichen Inhalt.
mcont
1
Das Einstellen des Hintergrunds auf transparent hat für mich gut funktioniert, als ich versucht habe, auf ein Raster zu fallen. Anscheinend brauchen Sie einen Hintergrund, damit der Treffer-Test stattfindet. Dank dieses Blogeintrags: codeinreview.com/136/enabling-drag-and-drop-over-a-grid-in-wpf
DustinA
35

Die Bilddatei ist im eParameter enthalten, der eine Instanz der DragEventArgsKlasse ist .
(Der senderParameter enthält einen Verweis auf das Objekt, das das Ereignis ausgelöst hat.)

Überprüfen Sie insbesondere das e.DataMitglied . Wie in der Dokumentation erläutert, wird hiermit ein Verweis auf das Datenobjekt ( IDataObject) zurückgegeben, das die Daten aus dem Drag-Ereignis enthält.

Die IDataObjectSchnittstelle bietet eine Reihe von Methoden zum Abrufen des Datenobjekts, nach dem Sie suchen. Sie möchten wahrscheinlich zunächst die Methode aufrufenGetFormats , um das Format der Daten herauszufinden, mit denen Sie arbeiten. (Ist es zum Beispiel ein tatsächliches Bild oder einfach der Pfad zu einer Bilddatei?)

Sobald Sie das Format der Datei identifiziert haben, die hineingezogen wird, rufen Sie eine der spezifischen Überladungen der GetDataMethode auf, um das Datenobjekt tatsächlich in einem bestimmten Format abzurufen.

Cody Grey
quelle
12

Um AR zu beantworten, beachten Sie bitte, dass Sie TextBoxFolgendes wissen müssen , wenn Sie Drop verwenden möchten .

TextBoxscheint bereits eine Standardbehandlung für zu haben DragAndDrop. Wenn Ihr Datenobjekt ein ist String, funktioniert es einfach. Andere Typen werden nicht behandelt und Sie erhalten den Effekt "Verbotene Maus" und Ihr Drop-Handler wird nie aufgerufen.

Es scheint , wie Sie Ihren eigenen Umgang mit ermöglichen können , e.Handledum wahr in einem PreviewDragOverEvent - 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);  
     }
}
Entwickler
quelle
1
In ARs Beispiel fehlt der PreviewDragOver-Handler, der wichtig ist, damit alles zusammenkommt. Ein großes Lob.
Greg Vogel