场景:为UI-Control启用了dragdrop的C#/ WPF应用程序。从Windows资源管理器拖动文件并将其放在UI-Control上时,会出现一个MessageBox。
问题:只要没有点击消息框(通过点击“确定”),Windows资源管理器就会被冻结,并且(可能)等待拖放事件返回。
问题:在显示MessageBox之前,有没有办法从等待中释放Windows资源管理器?那么“DragEventArgs”类的“Handled”属性呢?
代码:
private void OnDrop_ButtonOpen(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
MessageBox.Show(files[0]);
}
}
PS:其他类似问题存在。但是,没有“过早”返回事件的解决方案。
答案 0 :(得分:1)
如果我们看一下this documentation article about Drag and Drop operations,我们可以看到它说:
当用户启动拖放操作时,源会通过调用DoDragDrop来创建数据对象并启动拖动循环。
因此源窗口现在停留在由DoDragDrop
function启动的循环中。
当光标进入另一个窗口(称为目标窗口)时,DoDragDrop
函数将调用目标窗口的DragEnter
和DragOver
方法{ {1}}界面。
当您释放鼠标按钮以将数据放到目标窗口时,IDropTarget
函数将调用DoDragDrop
接口的Drop
方法。如果我们继续阅读......
当目标完成数据对象后, 将从IDropTarget :: Drop 返回。系统 返回源的DoDragDrop调用 ,以通知源数据传输已完成。
...我们发现在目标窗口退出其IDropTarget
方法之前,不会退出源窗口的DoDragDrop
调用。
在.NET中调用IDropTarget::Drop
方法时,它会引发IDropTarget::Drop
事件。引发事件意味着它调用所有附加的DragDrop
事件处理程序,并且因为这不是异步的,所以调用方法(DragDrop
)将被阻塞,直到调用所有IDropTarget::Drop
事件处理程序并且退出。
所以回答你的问题:不,你不能“过早地”回复它。它被每线程代码执行的标准逻辑阻止:一次一行。
您最好的选择是:
启动任务/显示消息框的新线程。您可能必须为此创建一个消息循环,但我不是百分百肯定。
创建您自己的消息框表单,并使用非模态调用DragDrop
显示它。