我已经在Borland的Turbo C + +环境中看到了这一点,但我不确定如何为我正在工作的c#应用程序做这件事。是否有最佳实践或陷阱需要注意?
在Windows窗体中,设置控件的AllowDrop属性,然后监听DragEnter事件和DragDrop事件。
当DragEnter事件触发时,将参数的AllowedEffect设置为非零的值(例如e.Effect = DragDropEffects.Move)。
DragEnter
AllowedEffect
e.Effect = DragDropEffects.Move
当DragDrop事件触发时,你将得到一个字符串列表。每个字符串都是被删除文件的完整路径。
DragDrop
你需要注意一个陷阱。在拖放操作中作为DataObject传递的任何类都必须是Serializable。因此,如果你试图传递一个对象,它不工作,确保它可以序列化,因为这几乎肯定是问题所在。这已经抓了我几次了!
另一个常见的陷阱是认为你可以忽略表单DragOver(或DragEnter)事件。我通常使用表单的DragOver事件来设置allowedeeffect,然后使用特定控件的DragDrop事件来处理已删除的数据。
一些示例代码:
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); } }
还有一个问题:
调用拖拽事件的框架代码会处理所有异常。您可能认为您的事件代码运行得很顺利,但它却到处都是异常。你看不到它们,因为框架窃取了它们。
这就是为什么我总是在这些事件处理程序中放入try/catch,这样我就知道它们是否抛出任何异常。我通常会放一个Debugger.Break();在接球部分。
在发布之前,在测试之后,如果一切看起来都正常,我会删除或用真正的异常处理替换这些异常。
注意windows vista/windows 7的安全权限——如果你以管理员身份运行Visual Studio,当你在Visual Studio中运行程序时,你将不能将文件从非管理员资源管理器窗口拖到程序中。拖相关事件甚至不会火!我希望这能帮助其他人不要浪费他们的生命……
这是我用来放置文件和/或文件夹充满文件的东西。在我的情况下,我只过滤*.dwg文件,并选择包括所有子文件夹。
*.dwg
fileList是一个IEnumerable或类似的在我的情况下被绑定到WPF控件…
fileList
IEnumerable
var fileList = (IList)FileList.ItemsSource;
有关该技巧的详细信息,请参见https://stackoverflow.com/a/19954958/492。
drop Handler…
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); } }
Judah Himango和Hans Passant的解决方案在设计器中可用(我目前使用VS2015):
你可以在WinForms和WPF中实现拖放。
你应该添加鼠标移动事件:
private void YourElementControl_MouseMove(object sender, MouseEventArgs e) { ... if (e.Button == MouseButtons.Left) { DoDragDrop(new DataObject(DataFormats.FileDrop, new string[] { PathToFirstFile,PathToTheNextOne }), DragDropEffects.Move); } ... }
你应该添加DragDrop事件:
private void YourElementControl_DragDrop(对象发送者,DragEventArgs e)
{ ... foreach (string path in (string[])e.Data.GetData(DataFormats.FileDrop)) { File.Copy(path, DirPath + Path.GetFileName(path)); } ... }
带有完整代码的源代码。
注意,为了实现这一点,你还需要在_drawEnter…中设置dragDropEffect。
private void Form1_DragEnter(object sender, DragEventArgs e) { Console.WriteLine("DragEnter!"); e.Effect = DragDropEffects.Copy; }
来源:在c# Winforms应用程序中拖放不工作