Bildschirm "Warten" in WPF anzeigen

7

Ich versuche, einen Dialog "Bitte warten" für eine lange laufende Operation anzuzeigen. Das Problem besteht darin, dass dies ein Singlethread ist, obwohl ich dem WaitScreen sage, dass es nie angezeigt wird. Gibt es eine Möglichkeit, die Sichtbarkeit dieses Bildschirms zu ändern und sofort anzuzeigen? Ich habe den Cursor-Aufruf als Beispiel eingefügt. Gleich nachdem ich das aufgerufen habe.Cursor wird der Cursor sofort aktualisiert. Das ist genau das Verhalten, das ich will.

%Vor%

WaitScreen ist nur ein Raster mit einem Z-Index von 99, den ich verstecke und zeige.

update: Ich möchte wirklich keinen Hintergrundarbeiter verwenden, es sei denn, ich muss. Es gibt eine Reihe von Stellen im Code, an denen dieser Start und dieser Stopp stattfinden.

    
Shaun Bowe 05.03.2009, 21:08
quelle

4 Antworten

15

Ich habe einen Weg gefunden! Danke an diesen Thread .

%Vor%

Diese Funktion muss direkt vor dem lang andauernden Vorgang aufgerufen werden. Dadurch wird der UI-Thread zur Aktualisierung gezwungen.

    
Shaun Bowe 05.03.2009, 21:22
quelle
17

Doing single threaded wird wirklich ein Schmerz sein, und es wird nie funktionieren, wie Sie möchten. Das Fenster wird schließlich in WPF schwarz und das Programm wird zu "Nicht reagieren" geändert.

Ich würde empfehlen, einen BackgroundWorker zu verwenden, um Ihre lang andauernde Aufgabe zu erledigen.

Es ist nicht so kompliziert. So etwas würde funktionieren.

%Vor%

Sie können dann das ProgressChanged-Ereignis betrachten, um gegebenenfalls einen Fortschritt anzuzeigen (denken Sie daran, WorkerReportsProgress auf true zu setzen). Sie können auch einen Parameter an RunWorkerAsync übergeben, wenn Ihre DoWork-Methoden ein Objekt benötigen (verfügbar in e.Argument).

Dies ist wirklich der einfachste Weg, anstatt zu versuchen, es singled threaded zu tun.

    
Ray 05.03.2009 21:12
quelle
4

Sehen Sie sich meine umfassende Recherche zu diesem sehr heiklen Thema an. Wenn Sie nichts tun können, um die tatsächliche Leistung zu verbessern, haben Sie folgende Möglichkeiten, eine wartende Nachricht anzuzeigen:

Option # 1 Führen Sie einen Code aus, um synchron eine wartende Nachricht in derselben Methode anzuzeigen, die die eigentliche Aufgabe ausführt. Setzen Sie diese Zeile vor einen langen Prozess:

%Vor%

Es verarbeitet ausstehende Nachrichten im Haupt-Dispatcher-Thread am Ende von Invoke () .

Hinweis: Grund für die Auswahl von Application.Current.Dispatcher, aber Dispatcher.CurrentDispatcher wird hier erklärt .

Option # 2 Zeigen Sie einen "Warte" -Bildschirm an und aktualisieren Sie die Benutzeroberfläche (ausstehende Meldungen verarbeiten).

Um es zu tun, haben WinForms Entwickler ausgeführt Application.DoEvents Methode. WPF bietet zwei Alternativen, um ähnliche Ergebnisse zu erzielen:

Option # 2.1 Mit der DispatcherFrame-Klasse .

Sehen Sie sich ein Beispiel aus MSDN an:

%Vor%

Option # 2.2 Ruft eine leere Aktion auf

%Vor%

Siehe Diskussionen welche (2.1 oder 2.2) besser ist hier . IMHO Option # 1 ist immer noch besser als # 2.

Option # 3 Zeigt eine wartende Nachricht in einem separaten Fenster an.

Es ist praktisch, wenn Sie keine einfache wartende Nachricht, sondern eine Animation anzeigen. Das Rendering einer Lade-Animation zur gleichen Zeit, zu der wir auf einen weiteren langen Render-Vorgang warten, ist ein Problem. Grundsätzlich benötigen wir zwei Rendering-Threads. Sie können nicht mehrere Rendering-Threads in einem einzigen Fenster haben, aber Sie können Ihre Ladeanimation in ein neues Fenster mit einem eigenen Rendering-Thread einfügen und dafür sorgen, dass es aussieht, als wäre es kein separates Fenster.

Lade WpfLoadingOverlay.zip von diesem GitHub (Es war ein Beispiel aus dem Artikel "", aber ich kann es nicht mehr im Web finden) oder sehen Sie sich die folgende Grundidee an:

%Vor%     
Alex Klaus 18.09.2013 04:10
quelle
3

Eine andere Möglichkeit besteht darin, Ihre lang laufende Routine als Funktion zu schreiben, die IEnumerable<double> zurückgibt, um den Fortschritt anzuzeigen, und einfach sagen:

%Vor%

Das würde zum Beispiel 30% des Weges angeben. Sie können dann einen WPF-Timer verwenden, um es im "Hintergrund" als kooperative Coroutine auszuführen.

Es wird hier mit Beispielcode detailliert beschrieben.

    
Daniel Earwicker 05.03.2009 21:35
quelle

Tags und Links