我曾在Borland的Turbo c++环境中看到过这一点,但我不确定如何在我正在开发的c#应用程序中实现这一点。是否有最佳实践或陷阱需要注意?


当前回答

一些示例代码:

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

其他回答

一些示例代码:

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

另一个常见的陷阱是认为你可以忽略表单DragOver(或DragEnter)事件。我通常使用表单的DragOver事件来设置allowedeeffect,然后使用特定控件的DragDrop事件来处理已删除的数据。

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

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

你应该添加鼠标移动事件:

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事件:

private void YourElementControl_DragDrop(对象发送者,DragEventArgs e)

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

源代码与完整的代码。

你需要注意一个陷阱。在拖放操作中作为数据对象传递的任何类都必须是可序列化的。因此,如果你试图传递一个对象,它不工作,确保它可以序列化,因为这几乎肯定是问题所在。这已经抓了我几次了!

还有一个问题:

调用拖拽事件的框架代码会处理所有异常。您可能认为您的事件代码运行得很顺利,但它却到处都是异常。你看不到它们,因为框架窃取了它们。

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

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