Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# DragDrop.DoDragDrop在将操作拖放到Excel时不返回_C#_Excel_Drag And Drop - Fatal编程技术网

C# DragDrop.DoDragDrop在将操作拖放到Excel时不返回

C# DragDrop.DoDragDrop在将操作拖放到Excel时不返回,c#,excel,drag-and-drop,C#,Excel,Drag And Drop,我的应用程序有一个简单的功能,它可以连接到Excel并在它们之间执行拖放操作。具体来说,我只是从我的应用程序中获取一些文本值,将它们拖到Excel中,然后将它们删除 这在90%的情况下都能正常工作,但奇怪的是,在某些时候,我的应用程序会冻结。我附加了调试器并暂停了执行,它被困在DragDrop.DoDragDrop-这个函数永远不会返回,我的应用程序将永远挂起 是否有办法确保DoDragDrop可以返回?或者某种超时?这种情况只有在我将数据放入Excel时才会发生,因此据我所知,删除正在完成,函

我的应用程序有一个简单的功能,它可以连接到Excel并在它们之间执行拖放操作。具体来说,我只是从我的应用程序中获取一些文本值,将它们拖到Excel中,然后将它们删除

这在90%的情况下都能正常工作,但奇怪的是,在某些时候,我的应用程序会冻结。我附加了调试器并暂停了执行,它被困在
DragDrop.DoDragDrop
-这个函数永远不会返回,我的应用程序将永远挂起

是否有办法确保
DoDragDrop
可以返回?或者某种超时?这种情况只有在我将数据放入Excel时才会发生,因此据我所知,删除正在完成,函数应该在我的应用程序中返回

以下是我使用的代码:

DragDrop.DoDragDrop(sender as DependencyObject, draggable.GetDragDropString(), DragDropEffects.Copy);
GetDragDropString()
只是一个函数,它返回要放入Excel的数据字符串。
sender
只是我正在拖动的UI组件。例如网格、编辑框、文本框等可以是其中的任何一种

谢谢你的帮助


编辑:由于在某些情况下,
DragDrop.DoDragDrop
返回存在问题,也许有人可以帮助编写一个适当的超时?我尝试过启动一个新的
线程
并让它超时,这在简单的情况下以及当线程中的工作不需要UI资源时都可以工作。但是,当我在一个新线程中调用
DoDragDrop
并超时时,它将抛出一个异常,表示该线程无法访问该对象,因为该对象属于另一个线程。所以我需要在同一个线程中调用这个函数。因此,本质上,当该函数在一定时间内无法返回时,我需要在UI线程上超时。

我认为以下内容应该可以完成这项工作,但我会在继续的过程中对其进行分解

public class DragDropTimer
{
    private delegate void DoDragDropDelegate();
    private System.Timers.Timer dragTimer;
    private readonly int interval = 3000;

    public DragDropTimer()
    {
        dragTimer = new System.Timers.Timer();
        dragTimer.Interval = interval;
        dragTimer.Elapsed += new ElapsedEventHandler(DragDropTimerElapsed);
        dragTimer.Enabled = false;
        dragTimer.AutoReset = false;
    }

    void DragDropTimerElapsed(object sender, ElapsedEventArgs e)
    {
        Initiate();
    }

    public void Initiate()
    {
        // Stops UI from freezing, call action async.
        DoDragDropDelegate doDragDrop = new DoDragDropDelegate(DragDropAction);

        // No async callback or object required
        doDragDrop.BeginInvoke(null, null);
    }

    private void DragDropAction()
    {
        dragTimer.Enabled = false; 

        // Do your work here. or do work before and disable your timer upto you.

    }

}
所以我们有一个基本类
DragDropTimer
。我们在构造函数上设置了所需的时间间隔,如果您愿意,您可能需要更改该时间间隔,我们在计时器已过时调用
dragdroptimerecursed


Initiate
是启动拖动所需的函数,它创建一个简单的委托,我们要求它执行
dragaAction
步骤,这是您执行所有工作的地方,计时器被禁用。只有在DragDrop成功时,才可以选择禁用计时器。如果计时器过期,我们再次调用
Initiate
重新启动。

另一个选项是以以下方式在单独的线程中执行drop

Task.Factory.StartNew( () => { ... } );

@HansPassant感谢您的回复-拖动始终由用户完成。你是说我需要在我的应用程序代码中处理Excel回调吗?就像你提到的DragEnter/Over/Drop电话?我只是假设如果用户自己将数据拖拽到Excel中,DoDragDrop函数将在之后返回。这种方法90%的时间都有效,但有时会冻结。