Jak przeciągać i upuszczać pliki do aplikacji?

251

Widziałem to w środowisku Turbo C ++ firmy Borland , ale nie jestem pewien, jak to zrobić w przypadku aplikacji C #, nad którą pracuję. Czy są jakieś sprawdzone metody lub gotówki?

Uwe Keim
źródło
Masz na myśli przeciągnij i upuść w aplikacji C # lub do C # IDE?
JamesSugrue
4
Oczywiście, aplikacja C #. Chce, aby jego aplikacja była przyjazna dla przeciągania i upuszczania.
SLA80
3
Więcej przydatnych odpowiedzi pod linkiem .
Venkatesh Kumar

Odpowiedzi:

505

Niektóre przykładowy kod:

  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
źródło
56
Oświadczenie: może nie działać podczas debugowania, jeśli uruchomisz program Visual Studio jako administrator w systemie Windows 7 lub jeśli uruchomisz program jako administrator. Zobacz tutaj
Matthieu
Jak uzyskać zawartość plików?
Burnsys,
3
@Burnsys, jeśli masz ścieżkę do pliku z operacji przeciągania, możesz czytać za pomocąio.File
Smith
1
Ugh, nie. Ustaw właściwość AllowDrop na True w projektancie i stamtąd ją uzasadnij.
Hans Passant,
2
Czy (string[])rzutowanie jest bezpieczne dla dowolnego FileDropsformatowanego zrzutu? To znaczy, czy można wygenerować taki FileDrop, który spowoduje niezgodny z prawem wyjątek rzutowania string[]? Mam problem z ustaleniem tego na podstawie dokumentów .
kdbanman,
140

Pamiętaj o prawach bezpieczeństwa systemu Windows vista / Windows 7 - jeśli korzystasz z programu Visual Studio jako administrator, nie będziesz mógł przeciągać plików z okna eksploratora innego niż administrator do swojego programu po uruchomieniu go z poziomu programu Visual Studio. Wydarzenia związane z przeciąganiem nawet się nie uruchomią! Mam nadzieję, że pomoże to komuś innemu nie marnować godzin życia ...

Wayne Uroda
źródło
6
@Wayne Uroda: Myślałem, że mój kod nie działa - do cholery dawał mi duży „Brak symbolu” jak ten en.wikipedia.org/wiki/File:ProhibitionSign2.svg . Potem zobaczyłem tę odpowiedź i uruchomiłem VS jako nieadministracyjny i presto działa! Stukrotne dzięki.
Derek W
Nie mogę ci za to wystarczająco podziękować, zrezygnowałbym, chyba że zdarzyło mi się znaleźć ten post! Jest tak samo ważny w systemie Windows 10 w 2017 r., Jak wtedy, gdy go napisałeś.
Culme,
42

W formularzach Windows ustaw właściwość AllowDrop formantu, a następnie nasłuchuj zdarzenia DragEnter i DragDrop.

Gdy DragEnterzdarzenie zostanie uruchomione, ustaw argument na AllowedEffectcoś innego niż brak (np e.Effect = DragDropEffects.Move.).

Gdy DragDropwydarzenie się uruchomi , otrzymasz listę ciągów znaków. Każdy ciąg jest pełną ścieżką do usuwanego pliku.

Judah Gabriel Himango
źródło
16

Musisz być świadomy gotcha. Każda klasa przekazywana jako obiekt DataObject w operacji przeciągania / upuszczania musi mieć możliwość szeregowania. Więc jeśli spróbujesz przekazać obiekt, który nie działa, upewnij się, że można go przekształcić do postaci szeregowej, ponieważ prawie na pewno jest to problem. Kilka razy mnie to złapało!

Phil Wright
źródło
14

Jeszcze jedna gotcha:

Kod frameworku wywołujący zdarzenia Drag pochłania wszystkie wyjątki. Możesz myśleć, że Twój kod zdarzenia działa płynnie, podczas gdy tryskają wyjątkami w każdym miejscu. Nie możesz ich zobaczyć, ponieważ kradnie je platforma.

Dlatego zawsze umieszczam try / catch w tych procedurach obsługi zdarzeń, po prostu wiem, czy zgłaszają jakieś wyjątki. Zwykle umieszczam Debugger.Break (); w części catch.

Przed wydaniem, po przetestowaniu, jeśli wszystko wydaje się zachowywać, usuwam je lub zastępuję prawdziwą obsługą wyjątków.

Guge
źródło
9

Innym powszechnym problemem jest myślenie, że możesz zignorować zdarzenia Form DragOver (lub DragEnter). Zwykle używam zdarzenia DragOver formularza do ustawienia Dozwolonego efektu, a następnie zdarzenia DragDrop określonej kontrolki do obsługi upuszczonych danych.

Craig Eddy
źródło
7

Oto coś, czego użyłem do upuszczania plików i / lub folderów pełnych plików. W moim przypadku szukałem*.dwg tylko pliki i postanowiłem uwzględnić wszystkie podfoldery.

fileListjest IEnumerablepodobny lub podobny W moim przypadku był związany z kontrolką WPF ...

var fileList = (IList)FileList.ItemsSource;

Zobacz https://stackoverflow.com/a/19954958/492 aby uzyskać szczegółowe informacje na temat tej sztuczki.

Uchwyt zrzutu ...

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

Rozwiązanie Judah Himango i Hansa Passanta jest dostępne w Designer (obecnie używam VS2015):

wprowadź opis zdjęcia tutaj

wprowadź opis zdjęcia tutaj

Roland
źródło
0

Możesz wdrożyć Drag & Drop w WinForms i WPF.

  • WinForm (Przeciągnij z okna aplikacji)

Powinieneś dodać zdarzenie mousemove:

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 (przeciągnij do okna aplikacji)

Powinieneś dodać zdarzenie DragDrop:

private void YourElementControl_DragDrop (nadawca obiektu, DragEventArgs e)

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

Źródło z pełnym kodem .

Ernest Rutherford
źródło