简而言之,我的代码当前对于面板上的dragenter和DragDrop事件看起来像这样(删除了错误处理):
private void dragPanel_dragenter(object sender,DragEventArgs e) { var filenames = (string[])e.Data.GetData(DataFormats.FileDrop,false); if (Path.GetExtension(filenames[0]) == ".xlsx") e.Effect = DragDropEffects.All; else e.Effect = DragDropEffects.None; } private void dragPanel_DragDrop(object sender,false); string filename = filenames[0]; // Do stuff }
我正在尝试在拖动文件时显示Excel图标,但我能得到的就是这个:
我在网上看到的任何地方(主要是在这个论坛上)说我需要实现自己的自定义光标,如果我想要显示一个特定的图标,但老实说我不相信.我使用完全相同的控件(这只是一个子集)截取了来自不同公司的多个应用程序的屏幕截图.请注意,它们都不是游标,图标只跟随光标:
Windows资源管理器:
谷歌浏览器:
Adobe Acrobat:
Microsoft Edge:
(相同的图标,但DragDropEffects可能设置为None)
所以我的结论是必须有一个共同的窗口控制,但它在哪里?所有这些公司都没有办法巧合地构建完全相同的设计和功能!
任何帮助,将不胜感激!
奖金问题:显然在Windows 10中,您不能拖放到以管理员身份运行的程序上,但Chrome绝对允许您这样做.您可以将Chrome作为管理员运行,并将文件拖到其上,而不会出现任何问题.谷歌使用什么魔力绕过这个安全功能?我想实现它,因为我的控件可能会在以管理员身份运行的程序中使用.
解决方法
它允许应用程序协商图像和图标显示.在您的情况下,Explorer已经使用IDragSourceHelper进行拖动图标协商,因此您所要做的就是将drop事件委托给DragDropHelper公开的IDropTargetHelper:
互操作性:
using IDataObject_Com = System.Runtime.InteropServices.ComTypes.IDataObject; [StructLayout(LayoutKind.Sequential)] public struct Win32Point { public int x; public int y; } [ComImport] [Guid("4657278A-411B-11d2-839A-00C04FD918D0")] public class DragDropHelper { } [ComVisible(true)] [ComImport] [Guid("4657278B-411B-11D2-839A-00C04FD918D0")] [InterfaceType(ComInterfaceType.InterfaceIsIUnkNown)] public interface IDropTargetHelper { void dragenter( [In] IntPtr hwndTarget,[In,MarshalAs(UnmanagedType.Interface)] IDataObject_Com dataObject,[In] ref Win32Point pt,[In] int effect); void DragLeave(); void DragOver( [In] ref Win32Point pt,[In] int effect); void Drop( [In,[In] int effect); void Show( [In] bool show); }
形成:
private IDropTargetHelper ddHelper = (IDropTargetHelper)new DragDropHelper(); private void Form1_DragDrop(object sender,DragEventArgs e) { e.Effect = DragDropEffects.copy; Point p = Cursor.Position; Win32Point wp; wp.x = p.X; wp.y = p.Y; ddHelper.Drop(e.Data as IDataObject_Com,ref wp,(int)e.Effect); } private void Form1_dragenter(object sender,DragEventArgs e) { e.Effect = DragDropEffects.copy; Point p = Cursor.Position; Win32Point wp; wp.x = p.X; wp.y = p.Y; ddHelper.dragenter(this.Handle,e.Data as IDataObject_Com,(int)e.Effect); } private void Form1_DragLeave(object sender,EventArgs e) { ddHelper.DragLeave(); } private void Form1_DragOver(object sender,DragEventArgs e) { e.Effect = DragDropEffects.copy; Point p = Cursor.Position; Win32Point wp; wp.x = p.X; wp.y = p.Y; ddHelper.DragOver(ref wp,(int)e.Effect); }
WPF版本基本相同,只有很小的变化:
private void Window_dragenter(object sender,DragEventArgs e) { e.Effects = DragDropEffects.copy; e.Handled = true; Point p = this.PointToScreen(e.GetPosition(this)); Win32Point wp; wp.x = (int)p.X; wp.y = (int)p.Y; ddHelper.dragenter(new WindowInteropHelper(this).Handle,(int)e.Effects); }
参考文献:
> PInvoke on IDropTargetHelper
> MSDN Blogs: Shell Style Drag and Drop in .NET (WPF and WinForms) – 涵盖源和目标实施.
> Chrome / Chromium DragDrop Target Helper.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。