Riz*_*Riz 6 c# wpf drag-and-drop
我正在开发一个 WPF 应用程序,它显示存储在远程服务器上的文件列表(就像保管箱一样)。我希望用户将它们拖放到桌面或任何文件夹上。有很多与此相关的问题,但没有一个真正给出完整的解决方案。
这是我正在使用的完整代码https://github.com/dotriz/VirtualDragDrop/
如果文件存储在本地系统上,这是一个非常简单的任务,但这里的文件位于远程服务器上,需要先下载。
唯一与此相关的文章是 13 年前发布的https://dlaa.me/blog/post/9923072。它也有一些问题,比如
无效的 FORMATETC 结构(HRESULT 异常:0x80040064 (DV_E_FORMATETC)
以下是标签的 MouseDown 事件中使用的代码。它使用上面给出的链接中的VirtualFileDataObject类
private void VirtualFile2_MouseButtonDown(object sender, MouseButtonEventArgs e)
{
var virtualFileDataObject = new VirtualFileDataObject();
virtualFileDataObject.SetData(new VirtualFileDataObject.FileDescriptor[]
{
new VirtualFileDataObject.FileDescriptor
{
Name = "test.zip",
ChangeTimeUtc = DateTime.Now.AddDays(-1),
StreamContents = stream =>
{
using(var webClient = new WebClient())
{
var data = webClient.DownloadData("https://somesite.com/test.zip");
stream.Write(data, 0, data.Length);
}
}
},
});
DoDragDropOrClipboardSetDataObject(e.ChangedButton, VirtualFile2, virtualFileDataObject, DragDropEffects.Copy);
}
private static void DoDragDropOrClipboardSetDataObject(MouseButton button, DependencyObject dragSource, VirtualFileDataObject virtualFileDataObject, DragDropEffects allowedEffects)
{
try
{
VirtualFileDataObject.DoDragDrop(dragSource, virtualFileDataObject, allowedEffects);
}
catch (COMException)
{
// Failure; no way to recover
}
}
Run Code Online (Sandbox Code Playgroud)
我可以成功使用提供的复制程序。当在不调试的情况下运行时,它至少可以在 Windows 10、11、x86 x64 的发布和调试配置中运行。
DV_E_FORMATETC (0x80040064 ) 只是一个标准错误代码,这意味着数据对象不支持所请求的剪贴板格式。此错误在复制/粘贴、拖放和剪贴板操作中很常见。
根本不起作用的是:
void System.Runtime.InteropServices.ComTypes.IDataObject.GetData(ref FORMATETC format, out STGMEDIUM medium)调试模式下运行时。我认为您无法调试 .NET 程序(使用当今的工具),并在DoDragDrop 函数调用中抛出断点或异常。
DoDragDrop是一个大的模态循环,它吃掉发送到窗口的大部分消息。不幸的是,由于某种原因,.NET 调试器工具或异常处理程序(在 clr.dll 中)似乎也在等待此循环。taskkill /im myprocess.exe /f因此,命中断点或处理异常会在程序本身(以及调试器中)中产生挂起,您只能通过硬方式(例如命令行)终止被调试进程来打破死锁。
所以我的建议是:
避免在这些代码部分放置断点
将这些函数包装在try/catch块中并使用一些非侵入式跟踪机制,如下所示:
void System.Runtime.InteropServices.ComTypes.IDataObject.GetData(ref FORMATETC format, out STGMEDIUM medium)
{
try
{
....
}
catch(Exception ex)
{
Trace.WriteLine("GetData Error: " + ex);
throw; // rethrow as is
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
561 次 |
| 最近记录: |