Wie ziehe ich Dateien per Drag & Drop in eine Anwendung?

251

Ich habe dies in Borlands Turbo C ++ - Umgebung gesehen, bin mir aber nicht sicher, wie ich es für eine C # -Anwendung tun soll, an der ich arbeite. Gibt es Best Practices oder Fallstricke, auf die Sie achten müssen?

Uwe Keim
quelle
Meinen Sie Drag & Drop in einer C # -Anwendung oder in die C # -IDE?
JamesSugrue
4
Natürlich C # -Anwendung. Er möchte seine Anwendung Drag & Drop-freundlich gestalten.
SLA80
3
Weitere nützliche Antworten unter Link .
Venkatesh Kumar

Antworten:

505

Einige Beispielcodes:

  public partial class Form1 : Form {
    public Form1() {
      InitializeComponent();
      this.AllowDrop = true;
      this.DragEnter += new DragEventHandler(Form1_DragEnter);
      this.DragDrop += new DragEventHandler(Form1_DragDrop);
    }

    void Form1_DragEnter(object sender, DragEventArgs e) {
      if (e.Data.GetDataPresent(DataFormats.FileDrop)) e.Effect = DragDropEffects.Copy;
    }

    void Form1_DragDrop(object sender, DragEventArgs e) {
      string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
      foreach (string file in files) Console.WriteLine(file);
    }
  }
Hans Passant
quelle
56
Haftungsausschluss: Möglicherweise funktioniert es beim Debuggen nicht, wenn Sie Visual Studio als Administrator in Windows 7 ausführen oder wenn Sie Ihr Programm als Administrator ausführen. Siehe hier
Matthieu
Wie bekommt man den Inhalt der Dateien?
Burnsys
3
@ Burnsys, wenn Sie den Dateipfad aus der Ziehoperation haben, dann können Sie mitio.File
Smith
1
Ugh, nein. Setzen Sie die AllowDrop-Eigenschaft im Designer auf True und begründen Sie sie von dort aus.
Hans Passant
2
Ist der (string[])Guss sicher für FileDropformatierte Tropfen? Das heißt, ist es möglich, eine zu generieren FileDrop, die eine illegale Besetzungsausnahme verursacht string[]? Ich habe Probleme, das aus den Dokumenten herauszufinden .
Kdbanman
140

Beachten Sie die Sicherheitsrechte von Windows Vista / Windows 7 - Wenn Sie Visual Studio als Administrator ausführen, können Sie keine Dateien aus einem Nicht-Administrator-Explorer-Fenster in Ihr Programm ziehen, wenn Sie es in Visual Studio ausführen. Die Drag-bezogenen Ereignisse werden nicht einmal ausgelöst! Ich hoffe, das hilft jemand anderem da draußen, keine Stunden seines Lebens zu verschwenden ...

Wayne Uroda
quelle
6
@ Wayne Uroda: Ich dachte, mein Code funktioniert nicht - zum Teufel gab es mir ein großes "Nein-Symbol" wie dieses en.wikipedia.org/wiki/File:ProhibitionSign2.svg . Dann habe ich diese Antwort gesehen und VS als Nicht-Administrator ausgeführt und schon funktioniert es! Tausend Dank.
Derek W
Ich kann dir nicht genug dafür danken, ich hätte aufgegeben, wenn ich diesen Beitrag nicht gefunden hätte! Es ist in Windows 10 im Jahr 2017 genauso gültig wie zu dem Zeitpunkt, als Sie es geschrieben haben.
Culme
42

Legen Sie in Windows Forms die AllowDrop-Eigenschaft des Steuerelements fest und warten Sie dann auf das DragEnter-Ereignis und das DragDrop-Ereignis.

Wenn das DragEnterEreignis ausgelöst wird, setzen Sie das Argument AllowedEffectauf etwas anderes als keines (ze.Effect = DragDropEffects.Move . ).

Wenn das DragDropEreignis ausgelöst wird, erhalten Sie eine Liste mit Zeichenfolgen. Jede Zeichenfolge ist der vollständige Pfad zu der Datei, die gelöscht wird.

Judah Gabriel Himango
quelle
16

Sie müssen sich einer Gotcha bewusst sein. Jede Klasse, die Sie beim Ziehen / Ablegen als DataObject weitergeben , muss serialisierbar sein. Wenn Sie also versuchen, ein Objekt zu übergeben, und es nicht funktioniert, stellen Sie sicher, dass es serialisiert werden kann, da dies mit ziemlicher Sicherheit das Problem ist. Das hat mich ein paar Mal erwischt!

Phil Wright
quelle
14

Noch ein Gotcha:

Der Framework-Code, der die Drag-Ereignisse aufruft, verschluckt alle Ausnahmen. Sie könnten denken, Ihr Ereigniscode läuft reibungslos, während es überall Ausnahmen gibt. Sie können sie nicht sehen, weil das Framework sie stiehlt.

Deshalb habe ich in diesen Event-Handlern immer einen Versuch / Fang gemacht, nur damit ich weiß, ob sie Ausnahmen auslösen. Normalerweise setze ich einen Debugger.Break (); im Fangteil.

Vor der Veröffentlichung, nach dem Testen, wenn sich alles zu verhalten scheint, entferne oder ersetze ich diese durch echte Ausnahmebehandlung.

Guge
quelle
9

Ein weiteres häufiges Problem ist, dass Sie die Ereignisse Form DragOver (oder DragEnter) ignorieren können. Normalerweise verwende ich das DragOver-Ereignis des Formulars, um den AllowedEffect festzulegen, und dann das DragDrop-Ereignis eines bestimmten Steuerelements, um die abgelegten Daten zu verarbeiten.

Craig Eddy
quelle
7

Hier ist etwas, das ich verwendet habe, um Dateien und / oder Ordner voller Dateien abzulegen. In meinem Fall habe ich nur nach *.dwgDateien gefiltert und alle Unterordner eingeschlossen.

fileListist ein IEnumerableoder ähnliches In meinem Fall war an eine WPF-Kontrolle gebunden ...

var fileList = (IList)FileList.ItemsSource;

Siehe https://stackoverflow.com/a/19954958/492 Informationen zu diesem Trick finden .

Der Drop-Handler ...

  private void FileList_OnDrop(object sender, DragEventArgs e)
  {
    var dropped = ((string[])e.Data.GetData(DataFormats.FileDrop));
    var files = dropped.ToList();

    if (!files.Any())
      return;

    foreach (string drop in dropped)
      if (Directory.Exists(drop))
        files.AddRange(Directory.GetFiles(drop, "*.dwg", SearchOption.AllDirectories));

    foreach (string file in files)
    {
      if (!fileList.Contains(file) && file.ToLower().EndsWith(".dwg"))
        fileList.Add(file);
    }
  }
CAD-Typ
quelle
3

Die Lösung von Judah Himango und Hans Passant ist im Designer verfügbar (ich verwende derzeit VS2015):

Geben Sie hier die Bildbeschreibung ein

Geben Sie hier die Bildbeschreibung ein

Roland
quelle
0

Sie können Drag & Drop in WinForms und WPF implementieren.

  • WinForm (Aus App-Fenster ziehen)

Sie sollten ein Mausbewegungsereignis hinzufügen:

private void YourElementControl_MouseMove(object sender, MouseEventArgs e)

    {
     ...
         if (e.Button == MouseButtons.Left)
         {
                 DoDragDrop(new DataObject(DataFormats.FileDrop, new string[] { PathToFirstFile,PathToTheNextOne }), DragDropEffects.Move);
         }
     ...
    }
  • WinForm (In App-Fenster ziehen)

Sie sollten das DragDrop-Ereignis hinzufügen:

private void YourElementControl_DragDrop (Objektabsender, DragEventArgs e)

    {
       ...
       foreach (string path in (string[])e.Data.GetData(DataFormats.FileDrop))
            {
                File.Copy(path, DirPath + Path.GetFileName(path));
            }
       ...
    }

Quelle mit vollständigem Code .

Ernest Rutherford
quelle