Bagaimana cara saya drag and drop file ke dalam aplikasi?

251

Saya telah melihat ini dilakukan di lingkungan Turbo C ++ Borland , tapi saya tidak yakin bagaimana melakukannya untuk aplikasi C # yang saya kerjakan. Apakah ada praktik terbaik atau tantangan yang harus diwaspadai?

Uwe Keim
sumber
Apakah maksud Anda seret dan lepas dalam aplikasi C # atau ke dalam C # IDE?
JamesSugrue
4
Tentu, C # Aplikasi. Dia ingin membuat aplikasi-nya ramah & seret.
SLA80
3
Jawaban yang lebih bermanfaat di tautan .
Venkatesh Kumar

Jawaban:

505

Beberapa kode contoh:

  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
sumber
56
Penafian: ini mungkin tidak berfungsi dalam debug jika Anda menjalankan Visual Studio sebagai admin di Windows 7, atau jika Anda menjalankan program Anda sebagai admin. Lihat di sini
Matthieu
Bagaimana Anda mendapatkan konten file?
Burnsys
3
@ Burnsys jika Anda memiliki filepath dari operasi drag, maka Anda dapat membaca menggunakanio.File
Smith
1
Ugh, tidak. Setel properti AllowDrop ke True dalam perancang dan berilah alasan untuk itu dari sana.
Hans Passant
2
Apakah para (string[])pemain aman untuk FileDropdrop yang diformat? Artinya, apakah mungkin untuk menghasilkan FileDropyang akan menyebabkan pengecualian pemain ilegal string[]? Saya mengalami kesulitan mencari tahu dari dokumen .
kdbanman
140

Waspadai hak keamanan windows vista / windows 7 - jika Anda menjalankan Visual Studio sebagai administrator, Anda tidak akan dapat menyeret file dari jendela penjelajah non-administrator ke dalam program Anda ketika Anda menjalankannya dari dalam visual studio. Peristiwa terkait seret bahkan tidak akan menyala! Saya harap ini membantu orang lain di luar sana untuk tidak membuang-buang waktu hidup mereka ...

Wayne Uroda
sumber
6
@Wayne Uroda: Saya pikir kode saya tidak berfungsi - heck itu memberi saya "Tidak ada simbol" besar seperti ini en.wikipedia.org/wiki/File:ProhibitionSign2.svg . Lalu saya melihat jawaban ini dan menjalankan VS sebagai non-admin dan presto berhasil! Terima kasih banyak.
Derek W
Tidak cukup berterima kasih untuk ini, saya akan menyerah kecuali saya kebetulan menemukan posting ini! Ini berlaku di Windows 10 pada 2017 seperti ketika Anda menulisnya.
Culme
42

Di Windows Forms, setel properti AllowDrop kontrol, lalu dengarkan acara DragEnter dan acara DragDrop.

Ketika DragEnteracara menyala, atur argumen AllowedEffectke sesuatu selain yang tidak ada (mis e.Effect = DragDropEffects.Move.).

Saat DragDropacara dimulai, Anda akan mendapatkan daftar string. Setiap string adalah path lengkap ke file yang dijatuhkan.

Yehuda Gabriel Himango
sumber
16

Anda harus menyadari gotcha. Setiap kelas yang Anda lewati sebagai DataObject dalam operasi seret / lepas harus Serializable. Jadi, jika Anda mencoba dan melewatkan objek, dan itu tidak berfungsi, pastikan itu dapat diserialisasi karena itu hampir pasti masalahnya. Ini telah menangkap saya beberapa kali!

Phil Wright
sumber
14

Gotcha lainnya:

Kode kerangka kerja yang memanggil Drag-events menelan semua pengecualian. Anda mungkin berpikir kode acara Anda berjalan dengan lancar, sementara itu memunculkan pengecualian di semua tempat. Anda tidak dapat melihat mereka karena kerangka kerja mencuri mereka.

Itu sebabnya saya selalu mencoba / menangkap dalam event handler ini, hanya supaya saya tahu jika mereka memberikan pengecualian. Saya biasanya meletakkan Debugger.Break (); di bagian tangkapan.

Sebelum dirilis, setelah pengujian, jika semuanya tampak berperilaku, saya menghapus atau mengganti ini dengan penanganan pengecualian nyata.

Besar
sumber
9

Gotcha umum lainnya adalah berpikir Anda dapat mengabaikan acara Form DragOver (atau DragEnter). Saya biasanya menggunakan acara DragOver Formulir untuk mengatur DiizinkanEffect, dan kemudian acara DragDrop kontrol tertentu untuk menangani data yang dijatuhkan.

Craig Eddy
sumber
7

Ini adalah sesuatu yang saya gunakan untuk meletakkan file dan / atau folder yang penuh dengan file. Dalam kasus saya, saya memfilter *.dwghanya untuk file dan memilih untuk memasukkan semua subfolder.

fileListadalah IEnumerableatau serupa Dalam kasus saya terikat ke kontrol WPF ...

var fileList = (IList)FileList.ItemsSource;

Lihat https://stackoverflow.com/a/19954958/492 untuk detail trik itu.

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 cowok
sumber
3

Solusi Judah Himango dan Hans Passant tersedia di Designer (Saya saat ini menggunakan VS2015):

masukkan deskripsi gambar di sini

masukkan deskripsi gambar di sini

Roland
sumber
0

Anda dapat menerapkan Drag & Drop di WinForms dan WPF.

  • WinForm (Seret dari jendela aplikasi)

Anda harus menambahkan acara 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 (Seret ke jendela aplikasi)

Anda harus menambahkan acara DragDrop:

batal pribadi YourElementControl_DragDrop (pengirim objek, DragEventArgs e)

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

Sumber dengan kode lengkap .

Ernest Rutherford
sumber