Noa*_*Gal 9 c# drag-and-drop winforms
我正在尝试将项目拖到资源管理器中.
该项应该导致文件下载,所以我使用了我在网上找到的一个例子CustomDataObject,当他实际需要流时调用一个事件来下载文件,然后我的应用程序执行繁重的工作并执行下载.
它在类似的剪贴板操作中工作得很好.
实际的文件下载也会导致我的应用程序中的一些UI更改.主要是在表单上更改"工作"图标,并在出现错误时弹出气球.
在我刚刚使用的剪贴板操作中InvokeRequired,BeginInvoke在需要时,确保在主线程上发生这些UI更改.在拖动操作中,UI线程正在等待从其返回DoDragDrop的事件,而正在由CustomDataObject另一个线程调用的事件被调用.当我尝试调用BeginInvoke或者InvokeUI线程仍在等待时,我无法完成丢弃.
关于如何在访问源应用程序的UI时允许跨应用程序拖放,是否有一些示例或推荐的最佳实践?
这是DataObjectEx我修改后的自己使用的原始CodeProject文章.我刚刚更改了GetFileContents方法来调用一个虚方法,该方法返回一个Stream包含从类继承的文件数据,并重写该虚方法以从Web获取文件.当我想要在获取文件时更改UI中的内容时出现问题.正如我之前所说 - 主要UI线程仍然"停留"在DoDragDrop方法调用上,因此我无法按时调用它来在下载文件之前和之后进行工作线程所需的UI更改.
如果这是一个标准的 WinForms 应用程序,那么您在应用程序中真正需要做的就是在 Form 中添加 DragEnter 和 DragDrop 的事件处理程序。
在 DragEnter 内部,您需要检查对象的类型以确保它是文件名:
private void MyForm_DragEnter(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
string[] files = e.Data.GetData(DataFormats.FileDrop) as string[];
if (files != null)
{
// Do additional checks here if needed, like check extensions
e.Effect = DragDropEffects.Copy;
return;
}
}
e.Effect = DragDropEffects.None;
}
Run Code Online (Sandbox Code Playgroud)
然后在您的 DragDrop 处理程序中,我只需存储文件名,然后激活计时器。这允许 DragDrop 立即返回,以便在您对文件进行任何可能需要时间的处理时,其他应用程序(在您的示例中为 Windows 资源管理器)不会挂起。在 DragDrop 完成之前, Drag Source不会返回。
private void MyForm_DragDrop(object sender, DragEventArgs e)
{
string[] files = e.Data.GetData(DataFormats.FileDrop) as string[];
if (files != null)
{
_filesToProcess.Text = files[0]; // Assuming this is declared at the Form level
// Schedule a timer to fire in a few miliseconds as a simple asynchronous method
_DragDropTimer.Interval = 50;
_DragDropTimer.Enabled = true;
_DragDropTimer.Start();
Activate(); // Activates the form and gives it focus
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1388 次 |
| 最近记录: |