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事件。
当
当
你需要意识到一点。在拖放操作中作为数据对象传递的任何类都必须是可序列化的。因此,如果您尝试传递一个对象,但它不工作,请确保它可以序列化,因为这几乎肯定是问题所在。这让我好几次出局了!
另一个问题是:
调用拖动事件的框架代码会吞咽所有异常。您可能认为您的事件代码运行得很顺利,而它却在到处涌出异常。你看不到它们,因为框架窃取了它们。
这就是为什么我总是在这些事件处理程序中放置一个try/catch,这样我就知道它们是否抛出任何异常。我通常在catch部分放一个debugger.break()。
在发布之前,在测试之后,如果一切都正常,我会删除这些异常或者用真正的异常处理来替换它们。
这里有一些我用来删除文件和/或文件夹的文件。在我的例子中,我只过滤
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):