关于C#:如何将文件拖放到应用程序中?

How do I drag and drop files into an application?

我在Borland的Turbo C++环境中看到了这一点,但是我不确定如何处理我正在使用的C语言应用程序。是否有最佳实践或需要注意的问题?


一些示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  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);
    }
  }

请注意Windows Vista/Windows 7安全权限-如果您以管理员身份运行Visual Studio,则从Visual Studio中运行文件时,将无法将文件从非管理员资源管理器窗口拖动到程序中。与拖动相关的事件甚至不会触发!我希望这能帮助其他人,而不是浪费他们的时间…


在Windows窗体中,设置控件的allowDrop属性,然后侦听DragCenter事件和DragDrop事件。

DragEnter事件触发时,将参数的AllowedEffect设置为非"无"(例如e.Effect = DragDropEffects.Move)。

DragDrop事件触发时,您将得到一个字符串列表。每个字符串都是要删除的文件的完整路径。


你需要意识到一点。在拖放操作中作为数据对象传递的任何类都必须是可序列化的。因此,如果您尝试传递一个对象,但它不工作,请确保它可以序列化,因为这几乎肯定是问题所在。这让我好几次出局了!


另一个问题是:

调用拖动事件的框架代码会吞咽所有异常。您可能认为您的事件代码运行得很顺利,而它却在到处涌出异常。你看不到它们,因为框架窃取了它们。

这就是为什么我总是在这些事件处理程序中放置一个try/catch,这样我就知道它们是否抛出任何异常。我通常在catch部分放一个debugger.break()。

在发布之前,在测试之后,如果一切都正常,我会删除这些异常或者用真正的异常处理来替换它们。


这里有一些我用来删除文件和/或文件夹的文件。在我的例子中,我只过滤*.dwg文件,并选择包括所有子文件夹。

fileListIEnumerable或类似的东西,在我的情况下,是受WPF控制的…

1
var fileList = (IList)FileList.ItemsSource;

有关该技巧的详细信息,请参阅https://stackoverflow.com/a/19954958/492。

放置处理程序…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  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);
    }
  }


另一个常见的方法是认为可以忽略窗体DragOver(或DragEnter)事件。我通常使用窗体的DragOver事件来设置allowedEffect,然后使用特定控件的DragDrop事件来处理丢弃的数据。


设计师提供了Judah Himango和Hans Passant的解决方案(我目前使用的是VS2015):enter image description hereenter image description here


推荐阅读