Làm cách nào để kéo và thả tệp vào một ứng dụng?


251

Tôi đã thấy điều này được thực hiện trong môi trường Turbo C ++ của Borland , nhưng tôi không chắc chắn cách thực hiện đối với ứng dụng C # mà tôi đang làm việc. Có thực hành tốt nhất hoặc gotchas để tìm ra?


Bạn có nghĩa là kéo và thả trong Ứng dụng C # hoặc vào IDE C #?
JamesSugrue

4
Nguồn, ứng dụng C #. Anh ấy muốn làm cho ứng dụng của mình kéo và thả thân thiện.
SLA80

3
Câu trả lời hữu ích hơn tại liên kết .
Venkatesh Kumar

Câu trả lời:


505

Một số mã mẫu:

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

56
Tuyên bố từ chối trách nhiệm: nó có thể không hoạt động trong gỡ lỗi nếu bạn chạy Visual Studio với tư cách quản trị viên trong Windows 7 hoặc nếu bạn chạy chương trình của mình với tư cách quản trị viên. Xem tại đây
Matthieu

Làm thế nào để bạn có được nội dung của các tập tin?
Burnsys

3
@Burnsys nếu bạn có filepath từ thao tác kéo, thì bạn có thể đọc bằng cách sử dụngio.File
Smith

1
Ừ, không. Đặt thuộc tính AllowDrop thành True trong trình thiết kế và giải thích nó từ đó.
Hans Passant

2
(string[])diễn viên an toàn cho bất kỳ FileDropthả định dạng? Đó là, có thể tạo ra một FileDropđiều sẽ gây ra ngoại lệ bất hợp pháp string[]không? Tôi gặp khó khăn khi tìm ra điều đó từ các tài liệu .
kdbanman

140

Lưu ý về quyền bảo mật của windows vista / windows 7 - nếu bạn đang chạy Visual Studio với tư cách quản trị viên, bạn sẽ không thể kéo các tệp từ cửa sổ thám hiểm không phải quản trị viên vào chương trình của bạn khi bạn chạy nó từ trong studio hình ảnh. Các sự kiện liên quan đến kéo thậm chí sẽ không bắn! Tôi hy vọng điều này sẽ giúp người khác ngoài kia không lãng phí hàng giờ trong cuộc sống của họ ...


6
@Wayne Uroda: Tôi nghĩ rằng mã của tôi không hoạt động - quái gì nó đã cho tôi một "Không biểu tượng" lớn như thế này en.wikipedia.org/wiki/File:ProhibitionSign2.svg . Sau đó, tôi thấy câu trả lời này và chạy VS với tư cách là một người không phải quản trị viên và nó hoạt động! Cảm ơn rất nhiều.
Derek W

Không thể cảm ơn bạn đủ cho điều này, tôi sẽ từ bỏ trừ khi tôi tình cờ tìm thấy bài viết này! Nó có giá trị trong Windows 10 năm 2017 như khi bạn viết nó.
Culme

42

Trong Windows Forms, đặt thuộc tính AllowDrop của điều khiển, sau đó lắng nghe sự kiện Drag Entry và sự kiện DragDrop.

Khi DragEntersự kiện kích hoạt, đặt đối số AllowedEffectthành một cái gì đó không phải là không (ví dụ e.Effect = DragDropEffects.Move).

Khi DragDropsự kiện diễn ra, bạn sẽ nhận được một danh sách các chuỗi. Mỗi chuỗi là đường dẫn đầy đủ đến tập tin bị loại bỏ.


16

Bạn cần phải nhận thức được một gotcha. Bất kỳ lớp nào bạn chuyển qua làm DataObject trong hoạt động kéo / thả phải được tuần tự hóa. Vì vậy, nếu bạn cố gắng vượt qua một đối tượng và nó không hoạt động, hãy đảm bảo rằng nó có thể được nối tiếp vì đó gần như chắc chắn là vấn đề. Điều này đã bắt tôi ra một vài lần!


14

Một Gotcha khác:

Mã khung gọi các sự kiện Kéo nuốt tất cả các ngoại lệ. Bạn có thể nghĩ rằng mã sự kiện của bạn đang chạy trơn tru, trong khi nó đang xuất hiện các ngoại lệ ở khắp mọi nơi. Bạn không thể nhìn thấy chúng vì khung đánh cắp chúng.

Đó là lý do tại sao tôi luôn đặt thử / bắt trong các trình xử lý sự kiện này, để tôi biết liệu họ có đưa ra bất kỳ ngoại lệ nào không. Tôi thường đặt một Debugger.Break (); trong phần bắt.

Trước khi phát hành, sau khi thử nghiệm, nếu mọi thứ dường như hoạt động, tôi loại bỏ hoặc thay thế chúng bằng xử lý ngoại lệ thực sự.


9

Một vấn đề phổ biến khác là nghĩ rằng bạn có thể bỏ qua các sự kiện Form DragOver (hoặc Drag Entry). Tôi thường sử dụng sự kiện DragOver của Form để đặt allowEffect và sau đó là sự kiện DragDrop của một điều khiển cụ thể để xử lý dữ liệu bị bỏ.


7

Đây là một cái gì đó tôi đã sử dụng để thả tập tin và / hoặc thư mục đầy tập tin. Trong trường hợp của tôi, tôi chỉ lọc *.dwgcác tệp và chọn bao gồm tất cả các thư mục con.

fileListlà một IEnumerablehoặc tương tự Trong trường hợp của tôi bị ràng buộc với điều khiển WPF ...

var fileList = (IList)FileList.ItemsSource;

Xem https://stackoverflow.com/a/19954958/492 để biết chi tiết về thủ thuật đó.

Người xử lý thả ...

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

3

Giải pháp của Judah Himango và Hans Passant có sẵn trong Nhà thiết kế (Tôi hiện đang sử dụng VS2015):

nhập mô tả hình ảnh ở đây

nhập mô tả hình ảnh ở đây


0

Bạn có thể triển khai Kéo và Thả trong WinForms và WPF.

  • WinForm (Kéo từ cửa sổ ứng dụng)

Bạn nên thêm sự kiện 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 (Kéo đến cửa sổ ứng dụng)

Bạn nên thêm sự kiện DragDrop:

private void YourEuityControl_DragDrop (người gửi đối tượng, DragEventArss e)

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

Nguồn với mã đầy đủ .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.