Przeciągnij i upuść pliki do WPF

106

Muszę upuścić plik obrazu do mojej aplikacji WPF. Obecnie zdarzenie jest uruchamiane, gdy upuszczam pliki, ale nie wiem, co dalej. Jak uzyskać obraz? Czy senderobiekt jest obrazem czy kontrolką?

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
źródło

Odpowiedzi:

211

To jest w zasadzie to, co chcesz zrobić.

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

Nie zapomnij również podłączyć zdarzenia w języku XAML, a także ustawić AllowDropatrybut.

<StackPanel Name="ImagePanel" Drop="ImagePanel_Drop" AllowDrop="true">
    ...
</StackPanel>
AR
źródło
awesome działa niesamowicie, po prostu zamieniono "HandleFileOpen (files [0]);" to „foreach (plik z ciągiem znaków w plikach) {Openfile (plik);}” - Dzięki :)
Eamonn McEvoy
1
Przepraszam :) Mam na myśli to, że przeciąganie i upuszczanie nie działa. AllowDropjest ustawiona na True, ale Dropprocedura obsługi zdarzeń nigdy nie jest wywoływana. Kiedy przeciągam plik przez okno, widzę okrągły symbol „odmowy”
mcont
4
GridJako element główny użyłem elementu Borderwewnętrznego z Backgroundwłaściwością ustawioną na coś (biały jest w porządku, ale nie jest przezroczysty). Wewnątrz Borderumieściłem rzeczywistą zawartość.
mcont
1
Ustawienie przezroczystego tła działało dobrze, gdy próbowałem upuścić na siatkę. Najwyraźniej potrzebujesz tła, aby przeprowadzić test trafienia. Dzięki temu wpisowi na blogu: codeinreview.com/136/eniring-drag-and-drop-over-a-grid-in-wpf
DustinA
1
Jedną z prawdziwych rzeczy jest to, że jeśli uruchomisz VisualStudio jako administrator - debuguj swoją aplikację - i przeciągniesz z FileExplorer jako użytkownik niebędący administratorem, kontekst zabezpieczeń jest inny i żadne zdarzenia przeciągania nie zostaną wywołane. Kosztowało mnie to 30 minut życia.
Hans Karlsen
35

Plik obrazu jest zawarty w eparametrze, który jest instancją DragEventArgsklasy .
( senderParametr zawiera odwołanie do obiektu, który wywołał zdarzenie).

W szczególności sprawdź e.Dataczłonka ; jak wyjaśnia dokumentacja, zwraca to odniesienie do obiektu danych ( IDataObject), który zawiera dane ze zdarzenia przeciągania.

IDataObjectInterfejs zapewnia szereg metod pobierania obiektu danych, że jesteś po. Prawdopodobnie będziesz chciał zacząć od wywołania GetFormatsmetody , aby znaleźć format danych, z którymi pracujesz. (Na przykład, czy jest to rzeczywisty obraz, czy po prostu ścieżka do pliku obrazu?)

Następnie, po zidentyfikowaniu formatu przeciąganego pliku, wywołasz jedno z określonych przeciążeń GetDatametody, aby faktycznie pobrać obiekt danych w określonym formacie.

Cody Gray
źródło
12

Dodatkowo, aby odpowiedzieć AR, pamiętaj, że jeśli chcesz użyć TextBoxupuszczenia, musisz znać następujące rzeczy.

TextBoxwydaje się mieć już domyślną obsługę DragAndDrop. Jeśli obiekt danych to a String, to po prostu działa. Inne typy nie są obsługiwane i otrzymujesz efekt Forbidden mouse, a twoja funkcja obsługi Drop nigdy nie jest wywoływana.

Wygląda na to, że możesz włączyć własną obsługę z e.Handledna true w programie PreviewDragOverobsługi zdarzeń.

XAML

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

DO#

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);  
     }
}
Deweloper
źródło
1
W przykładzie AR nie ma obsługi PreviewDragOver, która jest dość ważna, aby wszystko się połączyć. Sława.
Greg Vogel