关于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


推荐阅读

    linux文件异或命令?

    linux文件异或命令?,数字,系统,工作,管理,命令,数据,网络,文件,第一,单位,基

    linux文件复制的命令?

    linux文件复制的命令?,系统,文件,命令,目录,源文件,基本知识,位置,目标,选

    linux复制命令文件?

    linux复制命令文件?,系统,文件,命令,目录,基本知识,源文件,目标,文件夹,路

    linux下文件均分命令?

    linux下文件均分命令?,管理,情况,系统,工作,信息,地址,命令,目录,单位,设备,L

    linux的文件替换命令?

    linux的文件替换命令?,系统,工作,实时,命令,文件,批量,字符串,内容,方法,表

    linux查文件数量命令?

    linux查文件数量命令?,系统,数据,电脑,命令,文件,信息,代码,对比,软件,第三,l

    linux命令去重文件?

    linux命令去重文件?,系统,工作,命令,信息,数据,环境,代码,文件,目录,操作,Lin

    linux写大文件命令?

    linux写大文件命令?,服务,数据,第三,较大,基础,工具,设备,文件,大小,命令,lin

    linux查询文件夹命令?

    linux查询文件夹命令?,系统,软件,电脑,命令,文件,文件夹,单位,第三,档案,数

    linux多文件打包命令?

    linux多文件打包命令?,系统,工具,时间,代码,文件,命令,文件夹,目录,指令,格

    linux匹配文件名命令?

    linux匹配文件名命令?,系统,时间,发行,位置,工具,软件,名称,盘后,电脑,盘中,l

    linux上编辑文件命令?

    linux上编辑文件命令?,系统,信息,工作,状态,命令,文件,标准,检测,工具,设备,L

    改文件名linux命令?

    改文件名linux命令?,名字,软件,文件,命令,位置,系统,文件名,目录,指令,方面,l

    linux命令文件加锁?

    linux命令文件加锁?,数据,密码,系统,设备,代码,地址,名单,信息,数字,统一,请

    linux拼接文件命令?

    linux拼接文件命令?,文件,数据,命令,代码,时间,信息,系统,情况,管理,标准,Lin

    linux文件常用命令?

    linux文件常用命令?,工作,地址,信息,系统,命令,目录,标准,情况,管理,常用命

    文件写入linux命令?

    文件写入linux命令?,文件,命令,状态,系统,名称,时间,首次,数据,数字,内容,在l

    linux命令行设置语言?

    linux命令行设置语言?,系统,管理,环境,国家,工具,电脑,软件,文化,底部,语言,l

    linux命令写满文件?

    linux命令写满文件?,地址,工作,命令,系统,管理,文件,目录,标准,电脑,信息,Lin

    文件夹排序linux命令?

    文件夹排序linux命令?,系统,数字,信息,工作,时间,命令,管理,设备,单位,工具,