每当我想让用户拖动控件时,我都会调用该控件的DoDragDrop。
阻力& drop工作正常,但我对周围的事情有疑问:
DoDragDrop完全阻止表单,没有计时器事件跳转,没有处理绘制消息。
DoDragDrop不仅阻止了阻力和阻力。 drop操作,但直到目标程序完成drop事件(I.E. explorer.exe的suck代码)。根据其他程序的代码很糟糕。
我想从一个新线程调用DoDragDrop。
尝试了这个:
Thread dragThread = new Thread(() =>
{
Form frm = new Form();
frm.DoDragDrop("data", DragDropEffects.All);
});
dragThread.SetApartmentState(ApartmentState.STA);
dragThread.IsBackground = true;
dragThread.Start();
但它似乎不起作用。我的意思是:当从这样的其他线程执行DoDragDrop时,我的程序或其他程序中的其他控件不会接收拖放消息。
还有其他解决方案吗?
答案 0 :(得分:4)
DoDragDrop 方法停止处理事件,直到第一个鼠标事件(例如鼠标移动)。所以我发现的解决方法非常简单 - 你只需要在调用DoDragDrop之前用相同的鼠标位置模拟鼠标事件:
void XYZControl_MouseDown(object sender, MouseEventArgs e)
{
var senderControl = (Control) sender;
...
Cursor.Position = senderControl.PointToScreen(new Point(e.X, e.Y)); // Workaround!
if (DoDragDrop(senderControl, DragDropEffects.Move) == DragDropEffects.Move)
{
...
}
....
}
答案 1 :(得分:1)
你需要忘记使用一个线程,它只会向在该线程上创建的窗口发送D + D通知。哪个不是你的控件。
我对“代码很糟糕”的诊断做不了多少。 DoDragDrop()调用本身确实会阻塞,直到释放鼠标按钮。 COM代码内部的另一个消息循环将接管并传递Windows消息。计时器和绘图消息应该正常传递。在您发布一些重复代码之前,很难获得诊断。
答案 2 :(得分:1)
您可能希望DoDragDrop
退出并异步执行该作业。