2012-04-03 5 views
1

deaktiviert nicht aktivieren Ich habe den folgenden Code. Innerhalb desselben Codeblocks deaktiviere ich ein Steuerelement und aktiviere es dann, aber es scheint nicht zu funktionieren und bleibt der ursprüngliche IsEnable-Status.Kann ein Steuerelement in demselben Block

// Button never enable 
public void Foo() 
{ 
    button1.IsEnabled = false 
    Thread.Sleep(3000); 
    button1.IsEnabled = true; 
    Thread.Sleep(3000); 
    button1.IsEnabled = false; 
} 

Antwort

4

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.

+0

+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

+0

Ich habe eine Erklärung hinzugefügt. –

+0

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

1

Wenn Sie Sleep aufrufen, wird der aktuelle Thread angehalten und die Benutzeroberfläche wird eingefroren (wenn Sie versuchen, auf die Benutzeroberfläche zu klicken, wird sie grau dargestellt), bis der Thread geweckt wird. Der Thread schläft also für 6 Sekunden und Sie werden nicht bemerken, dass die Schaltfläche aktiviert war. Am Ende bleibt die Schaltfläche deaktiviert.

Sie sollten Ihren Code in einem anderen Thread mit Dispatcher ausführen.

0

Wie von anderen Benutzern angegeben, verarbeitet der UI-Thread Ereignisse in der Warteschlange. Wenn Ihre Funktion im Benutzeroberflächenthread aufgerufen wird, kann sie keine Aktualisierungen an der Benutzeroberfläche durchführen, bis die aktuelle beendet ist.

NET hat eine Reihe von Threading-Optionen wie Background bieten, Faden, Thread usw.

Die neuere NET Framework bietet auch die async/await Methode der GUI-Thread zu erlauben, andere Arbeiten während einer Veranstaltung zu tun.

Verwandte Themen