来自另一个线程的DoDragDrop()

时间:2010-08-21 16:40:32

标签: c# winforms multithreading drag-and-drop blocking

每当我想让用户拖动控件时,我都会调用该控件的DoDragDrop。

阻力& drop工作正常,但我对周围的事情有疑问:

  1. DoDragDrop完全阻止表单,没有计时器事件跳转,没有处理绘制消息。

  2. DoDragDrop不仅阻止了阻力和阻力。 drop操作,但直到目标程序完成drop事件(I.E. explorer.exe的suck代码)。根据其他程序的代码很糟糕。

  3. 我想从一个新线程调用DoDragDrop。

    尝试了这个:

    Thread dragThread = new Thread(() =>
    {
        Form frm = new Form();
        frm.DoDragDrop("data", DragDropEffects.All);
    });
    
    dragThread.SetApartmentState(ApartmentState.STA);
    dragThread.IsBackground = true;
    dragThread.Start();
    

    但它似乎不起作用。我的意思是:当从这样的其他线程执行DoDragDrop时,我的程序或其他程序中的其他控件不会接收拖放消息。

    还有其他解决方案吗?

3 个答案:

答案 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退出并异步执行该作业。

Here is the answer.