Zunächst einmal: Es ist nicht so seltsam, dass die Schaltfläche nicht aktiviert ist, nachdem die Foo
Methode ausgeführt wurde, da die letzte Zeile die Schaltfläche deaktiviert.
Wenn Sie die aktivierte Statusänderung der Schaltfläche "sehen" möchten, müssen Sie die Fenstermeldungen vor dem Schlafen verarbeiten. Thread.Sleep
bewirkt, dass der UI-Thread in den Ruhezustand versetzt wird, sodass die Benutzeroberfläche nicht aktualisiert wird. Was Sie tun müssen, ist, dass die Anwendung alle ausstehenden Fenstermeldungen behandelt.
public static void DoEvents()
{
if (Application.Current != null)
Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new ThreadStart(delegate { }));
}
public void Foo()
{
button1.IsEnabled = false
DoEvents();
Thread.Sleep(3000);
button1.IsEnabled = true;
DoEvents();
Thread.Sleep(3000);
button1.IsEnabled = false;
}
EDIT
Weitere Erläuterungen:
Wenn der erste Thread.Sleep
genannt wird, die Schaltfläche deaktiviert ist (IsEnabled
ist false
). Dann, nachdem Sie 3 Sekunden gewartet haben, stellen Sie die Schaltfläche auf aktiviert und danach wieder aus. Die Schaltfläche befindet sich tatsächlich in diesem Status, aber es gibt keine visuelle Rückmeldung (wie in: Wenn Sie das Formular betrachten, sehen Sie die Schaltfläche "blink" nicht).
Dies liegt daran, dass Sie den UI-Thread blockieren, indem Sie Thread.Sleep
aufrufen. Dies verhindert, dass das Fenster Fenstermeldungen erhält, die dem Fenster mitteilen, wann es sich selbst oder eines seiner untergeordneten Elemente neu streichen soll (die Schaltfläche "weiß" nicht, dass es grau sein sollte).
Sie müssen dem Fenster also eine Chance geben, die Nachrichten zu empfangen und seine untergeordneten Elemente zu aktualisieren. In Windows Forms-Anwendungen wurde dies mit Application.DoEvents
durchgeführt, wodurch alle ausstehenden Fenstermeldungen verarbeitet wurden.
Es gibt nicht so etwas in WPF als Application.DoEvents
, aber der Code, den ich geschrieben habe emuliert dies durch ein Thread
spwaning, die nichts tut - aber das nur wenig Zeit zwischen der Schaltfläche aktivierten Zustand zu ändern und dem UI-Thread blockiert ist genug für die Schaltfläche Kontrolle, um sich neu zu streichen.
+1 gearbeitet. Aber Erklärung nicht klar. Nachdem das erste Thread.Sleep beendet ist, sollte die Schaltfläche vor dem zweiten Thread.Sleep aktiviert werden. Ich sollte immer noch eine Änderung im Zustand der Tasten bemerken. Nein? – KMC
Ich habe eine Erklärung hinzugefügt. –
Danke, aber hmm ... sobald der erste Thread.Sleep endet, sollte die Benutzeroberfläche entsperrt werden, um visuelles Feedback zu ermöglichen, bevor der zweite Thread.Sleep die Benutzeroberfläche erneut blockiert. Ich sehe also immer noch nicht, wie der Knopf nicht blinkt. – KMC