【问题标题】:How do I drag and drop files into an application?如何将文件拖放到应用程序中?
【发布时间】:2010-09-09 06:37:38
【问题描述】:

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

【问题讨论】:

  • 您的意思是拖放到 C# 应用程序中还是拖放到 C# IDE 中?
  • 当然,C# 应用程序。他想让他的应用程序拖放友好。
  • 更多有用的答案在link

标签: c# winforms drag-and-drop


【解决方案1】:

一些示例代码:

  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 7 中以管理员身份运行 Visual Studio,或者以管理员身份运行程序,它可能无法在调试中工作。见here
  • @Burnsys 如果你有拖动操作的文件路径,那么你可以使用io.File阅读
  • 该类不应该是密封类以避免对this.AllowDrop 进行虚拟调用吗? stackoverflow.com/questions/119506/…
  • 呃,不。在设计器中将 AllowDrop 属性设置为 True 并从那里推理出来。
  • 对于任何FileDrop 格式的drop,(string[]) cast 是否安全?也就是说,是否有可能生成一个FileDrop 会导致string[] 的非法转换异常?我无法从the docs 弄清楚这一点。
【解决方案2】:

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

【讨论】:

  • @Wayne Uroda:我认为我的代码不起作用 - 见鬼,它给了我一个像 en.wikipedia.org/wiki/File:ProhibitionSign2.svg 这样的大“无符号”。然后我看到了这个答案,并以非管理员身份运行了 VS,然后它就可以工作了!谢谢一百万。
  • 不能感谢你,除非我碰巧找到这篇文章,否则我会放弃的!它在 2017 年的 Windows 10 中与您编写它时一样有效。
【解决方案3】:

在 Windows 窗体中,设置控件的 AllowDrop 属性,然后监听 DragEnter 事件和 DragDrop 事件。

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

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

【讨论】:

  • 效果很好
【解决方案4】:

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

【讨论】:

    【解决方案5】:

    还有一个问题:

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

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

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

    【讨论】:

      【解决方案6】:

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

      【讨论】:

        【解决方案7】:

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

        fileListIEnumerable 或类似的在我的情况下绑定到 WPF 控件...

        var fileList = (IList)FileList.ItemsSource;
        

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

        drop 处理程序 ...

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

        【讨论】:

          【解决方案8】:

          Designer中提供了Judah Himango和Hans Passant的解决方案(我目前用的是VS2015):

          【讨论】:

          • 在你也使用 DragEnter 然后设置 e.Effect = DragDropEfects.Move 或类似的东西之前,这不会起作用。谢谢
          【解决方案9】:

          您可以在 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 事件:

          private void YourElementControl_DragDrop(object sender, DragEventArgs e)

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

          Source with full code.

          【讨论】:

            【解决方案10】:

            请注意,要使其正常工作,您还需要在 _drawEnter 中设置 dragDropEffect...

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

            来源:Drag and Drop not working in C# Winforms Application

            【讨论】:

              猜你喜欢
              • 2013-03-06
              • 1970-01-01
              • 2022-09-24
              • 1970-01-01
              • 2013-09-17
              • 2023-03-19
              • 1970-01-01
              相关资源
              最近更新 更多