263

我已经在 Borland 的Turbo C++环境中看到了这一点,但我不确定如何为我正在开发的 C# 应用程序执行此操作。是否有需要注意的最佳实践或陷阱?

4

10 回答 10

527

一些示例代码:

  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);
    }
  }
于 2008-09-18T02:26:35.033 回答
152

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

于 2011-01-25T04:10:03.280 回答
46

In Windows Forms, set the control's AllowDrop property, then listen for DragEnter event and DragDrop event.

When the DragEnter event fires, set the argument's AllowedEffect to something other than none (e.g. e.Effect = DragDropEffects.Move).

When the DragDrop event fires, you'll get a list of strings. Each string is the full path to the file being dropped.

于 2008-09-16T01:58:30.003 回答
16

你需要知道一个陷阱。在拖放操作中作为DataObject传递的任何类都必须是可序列化的。因此,如果您尝试传递一个对象,但它不起作用,请确保它可以被序列化,因为这几乎肯定是问题所在。这让我抓到了好几次!

于 2008-09-16T02:11:28.940 回答
14

另一个问题:

调用 Drag-events 的框架代码会吞下所有异常。您可能会认为您的事件代码运行平稳,而它却到处涌现异常。您看不到它们,因为框架窃取了它们。

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

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

于 2008-11-18T21:21:16.490 回答
9

另一个常见的问题是认为您可以忽略 Form DragOver(或 DragEnter)事件。我通常使用 Form 的 DragOver 事件来设置 AllowedEffect,然后使用特定控件的 DragDrop 事件来处理拖放的数据。

于 2008-09-16T02:32:48.750 回答
9

这是我用来删除文件和/或充满文件的文件夹的东西。在我的情况下,我只过滤*.dwg文件并选择包含所有子文件夹。

fileList是一个IEnumerable或类似的在我的情况下绑定到一个 WPF 控件...

var fileList = (IList)FileList.ItemsSource;

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

下降处理程序...

  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);
    }
  }
于 2016-04-19T14:25:36.793 回答
3

Judah Himango 和 Hans Passant 的解决方案在 Designer 中可用(我目前使用的是 VS2015):

在此处输入图像描述

在此处输入图像描述

于 2018-02-05T10:10:45.420 回答
0

您可以在 WinForms 和 WPF 中实现拖放。

  • WinForm(从应用程序窗口拖动)

您应该添加 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(拖动到应用程序窗口)

您应该添加 DragDrop 事件:

私人无效YourElementControl_DragDrop(对象发送者,DragEventArgs e)

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

带有完整代码的源代码

于 2020-04-27T09:47:39.890 回答
0

请注意,为此,您还需要在 _drawEnter 中设置 dragDropEffect...

private void Form1_DragEnter(object sender, DragEventArgs e)
{
    Console.WriteLine("DragEnter!");
    e.Effect = DragDropEffects.Copy;
}

来源:拖放在 C# Winforms 应用程序中不起作用

于 2020-07-16T22:32:10.943 回答