it-swarm-vi.tech

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

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 ứ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?

225
Samuel Paul

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);
    }
  }
473
Hans Passant

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ổ Explorer 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ọ ...

127
Wayne Uroda

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 sự kiện DragEnter kích hoạt, hãy đặt AllowedEffect của đối số thành một cái gì đó không phải là không (ví dụ: e.Effect = DragDropEffects.Move).

Khi sự kiện DragDrop kích hoạt, 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ỏ.

40
Judah Gabriel Himango

Bạn cần phải nhận thức được một gotcha. Bất kỳ lớp nào bạn vượt qua như 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!

16
Phil Wright

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 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ự.

10
Guge

Đâ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 các tệp *.dwg và chọn bao gồm tất cả các thư mục con.

fileList là một IEnumerable hoặ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);
    }
  }
7
CAD bloke

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ỏ.

6
Craig Eddy

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):  enter image description here  enter image description here

0
Roland