2010-06-06 10 views
10

ich eine WPF-Anwendung zu schreiben, die MVVM Muster verwendet wird, basiert auf dem folgenden Artikel: WPF Apps With The Model-View-ViewModel Design Patternprogramatic Neubewertung von MVVM-Befehl des „ausführen kann“ Zustand

Ich habe zwei Tasten auf meiner Ansicht mit den Tasten " Befehl "Eigenschaft gebunden (mit Datenbindung) an eine gegebene Instanz der RelayCommand Klasse (siehe" Abbildung 3 Die RelayCommand Klasse "aus dem obigen Artikel). Die RelayCommand-Klasse unterstützt die Überprüfung, ob der angegebene Befehl ausgeführt werden kann.

WPF deaktiviert automatisch Schaltflächen, deren Befehl nicht ausgeführt werden kann.

Jeder meiner Befehle (in der ViewModel-Klasse) startet eine Hintergrundoperation, und der Befehl kann erst wieder ausgeführt werden, wenn die Hintergrundoperation abgeschlossen ist. Die RelayCommand-Instanzen haben Informationen darüber, ob die Hintergrundoperation noch funktioniert oder beendet ist.

Mein Problem ist folgendes: nach dem Drücken einer der Tasten, gehen die Tasten automatisch deaktiviert (was OK ist), weil die Hintergrund-Operation gestartet und der Befehl nicht ausgeführt werden kann, bis es beendet ist, aber nachdem der Vorgang beendet wurde Die Schaltflächen werden nicht automatisch aktiviert, da das Prädikat "Kann ausgeführt werden" des Befehls nicht automatisch neu ausgewertet wird. Die Neubewertung kann manuell ausgelöst werden, indem Sie die Anwendung loslassen und den Fokus wiederherstellen (indem Sie ALT + TAB drücken). Nach diesem Trick werden die Schaltflächen erneut aktiviert.

Wie kann ich den Status der Schaltflächen 'Befehl kann ausführen' programmatisch neu bewerten?

Antwort

20

können Sie InvalidateRequerySuggested rufen die Befehlsmanager zu informieren, dass CanExecute erneut abgefragt werden soll:

CommandManager.InvalidateRequerySuggested(); 

http://msdn.microsoft.com/en-us/library/system.windows.input.commandmanager.invalidaterequerysuggested.aspx

Diese auf abhängt, ob die bestimmte ICommand Umsetzung der ICommand.CanExecuteChanged Muster ordnungsgemäß umgesetzt hat , also YMMV.

aktualisieren

Zum Beispiel verwende ich Prism, das seine eigene Basisimplementierung ICommand hat: DelegateCommand. Ich finde, dass das Aufrufen von RaiseCanExecuteChanged() auf einem DelegateCommand in Prism für mich funktioniert.

Update 2

Und sicher, dass Sie InvalidateRequerySuggested() auf dem UI-Thread aufrufen. Verwenden Sie ggf. den Dispatcher, um den Anruf zu tätigen.

+0

Dies ist das gleiche, was meine erste Vermutung war, aber aus einem unbekannten Grund für mich scheint es nicht zu funktionieren. Ich rufe diese statische Methode ("CommandManager.InvalidateRequerySuggested") jedes Mal, wenn der Status des Programms (wie Idle, Working, PendingStop usw.) ändert, ist es nur diese Statuseigenschaft, die in den canExecute-Handler verwendet wird. Dennoch scheint es nicht zu funktionieren (obwohl ich zustimme, dass es sollte). BTW, gehen Sie und überprüfen Sie die ICommand-Implementierung, es ist in dem Artikel, auf den ich zuvor verwiesen, Abbildung 3. – dzs

+0

Ja, es hängt wirklich davon ab, wie ICommand implementiert wurde. Ich habe meine Antwort aktualisiert, wie ich CanExecute in Prism erneut abgefragt habe. Ich werde mir den Artikel ansehen, den Sie verfolgen. –

+0

Ist dies etwas mit der Ausführung von InvalidateRequerySuggested() in einem Thread ohne Benutzeroberfläche zu tun?Versuchen Sie es mit dem Dispatcher, um es aufzurufen, damit es im UI-Thread aufgerufen wird. –

Verwandte Themen