2016-02-02 12 views
6

Moja aplikacja ma prostą funkcję, w której łączy się z programem Excel i wykonuje operacje przeciągania między nimi. W szczególności, po prostu biorę niektóre wartości tekstowe z mojej aplikacji, przeciągając je do Excela i upuszczając je.DragDrop.DoDragDrop nie wraca podczas wykonywania operacji upuszczania w programie Excel

Działa to 90% czasu, ale o dziwo, moja aplikacja po prostu zawiesza się. Załączam debugger i wstrzymuję wykonanie, i utknie na DragDrop.DoDragDrop - ta funkcja nigdy nie wróci i moja aplikacja na zawsze się zawiesi.

Czy istnieje sposób na zapewnienie, aby DoDragDrop mógł powrócić? Albo jakiś czas oczekiwania? Zdarza się to tylko wtedy, gdy upuszczam dane do Excela, więc o ile wiem, kropla jest wykonywana, a funkcja powinna powrócić w mojej aplikacji.

Oto kod używam:

DragDrop.DoDragDrop(sender as DependencyObject, draggable.GetDragDropString(), DragDropEffects.Copy); 

GetDragDropString() jest tylko funkcja, która zwraca ciąg danych do spadku w programie Excel. sender to tylko składnik interfejsu użytkownika, który przeciągam. Podobnie jak siatka, pole edycji, pole tekstowe itp. Może być jednym z nich.

Dzięki za pomoc!

EDYCJA: Ponieważ w niektórych przypadkach występuje problem z DragDrop.DoDragDrop, być może ktoś może pomóc w napisaniu odpowiedniego limitu czasu? Próbowałem uruchomić nowy Thread i mieć timeout, który działa w prostych przypadkach i gdy praca w wątku nie wymaga zasobów interfejsu użytkownika. Jednak, gdy zadzwonię pod numer DoDragDrop w nowym wątku z limitem czasu, zostanie zgłoszony wyjątek, w którym wątek nie może uzyskać dostępu do obiektu, ponieważ jest nim inny wątek. Muszę więc wywołać tę funkcję w tym samym wątku. Zasadniczo potrzebuję limitu czasu w wątku interfejsu użytkownika, gdy funkcja nie powiedzie się w określonym czasie.

+0

@HansPassant dzięki za odpowiedzi - Drag jest zawsze wykonywane przez użytkownika. Czy mówisz, że muszę obsługiwać wywołania zwrotne programu Excel w moim kodzie aplikacji? Jak wspomniałeś o rozmowach DragEnter/Over/Drop? Właśnie założyłem, że jeśli użytkownik przeciągnie dane do samego Excela, funkcja DoDragDrop powróci później. Działa to w 90% przypadków, ale czasami zamarza. – ryrich

Odpowiedz

1

myślę dodaje powinien wykonać zadanie, ale będę go rozkładać jak idę wzdłuż

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. 

    } 

} 

Więc mamy podstawową klasę DragDropTimer. Ustawiamy przedział, który chcemy na konstruktorze, możesz to zmienić, jeśli chcesz i zadzwonimy do DragDropTimerElapsed na czas, który upłynął.

Initiate jest funkcja trzeba zacząć przeciągać jego tworzy prosty delegata i pytamy go wykonać DragAction kroki, w tym miejscu można wykonać całą pracę, a zegar zostanie wyłączony. Możesz wyłączyć timer tylko wtedy, gdy DragDrop się powiedzie. Jeśli upłynie czas, ponownie zadzwonimy pod numer Initiate, aby rozpocząć od nowa.

0

Kolejne opcje to wykonać spadek w osobnym wątku w następujący sposób

Task.Factory.StartNew(() => { ... }); 
Powiązane problemy