2010-06-06 14 views
10

Piszę aplikacji WPF przy użyciu wzorca MVVM, w oparciu o następujący artykuł: WPF Apps With The Model-View-ViewModel Design PatternZautomatyzowane ponownej oceny MVVM polecenia użytkownika „można wykonać” stan

mam dwa przyciski na mój widok z przycisków " Polecenie "własność związana (z powiązaniem danych) z danym wystąpieniem klasy RelayCommand (patrz" Rysunek 3 Klasa RelayCommand "z powyższego artykułu). Klasa RelayCommand obsługuje sprawdzanie, czy dana komenda może zostać wykonana.

WPF automatycznie wyłącza przyciski, których polecenia nie można wykonać.

Każde z moich poleceń (w klasie ViewModel) rozpoczyna operację w tle, a polecenie nie może być wykonane ponownie, dopóki operacja w tle nie zostanie zakończona. Instancje RelayCommand mają informację, czy operacja w tle nadal działa, czy jest ukończona.

Mój problem jest następujący: po naciśnięciu któregokolwiek z przycisków, przyciski automatycznie się wyłączają (co jest w porządku), ponieważ rozpoczęło się działanie w tle i polecenie nie może być wykonane, dopóki nie zostanie zakończone, ale po zakończeniu operacji przyciski nie włączają się automatycznie, ponieważ ich polecenie "może być wykonane" nie jest automatycznie oceniane. Ponowna ocena może zostać uruchomiona ręcznie przez zwolnienie aplikacji i odzyskanie ostrości (poprzez naciśnięcie klawisza ALT + TAB). Po wykonaniu tej sztuczki przyciski zostaną ponownie włączone.

Jak mogę programowo przewartościować polecenia przycisków "można wykonać"?

Odpowiedz

20

Można zadzwonić InvalidateRequerySuggested na poleceń CommandManager powiadomić, że CanExecute należy ponownie zapytał:

CommandManager.InvalidateRequerySuggested(); 

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

To zależy od tego, czy konkretna realizacja ICommand został prawidłowo wdrożony wzór ICommand.CanExecuteChanged , więc YMMV.

Aktualizacja

Na przykład, używam Prism, który ma swój własny realizacja baza ICommand: DelegateCommand. Uważam, że wywołanie funkcji RaiseCanExecuteChanged() na DelegateCommand in Prism działa dla mnie.

Aktualizacja 2

I upewnij się, że dzwonisz InvalidateRequerySuggested() w wątku UI. W razie potrzeby użyj Dyspozytora, aby wykonać połączenie.

+0

To jest to samo, co moje pierwsze przypuszczenie, ale z jakiegoś niewiadomego powodu dla mnie to nie działa. Wywołuję tę metodę statyczną ("CommandManager.InvalidateRequerySuggested") za każdym razem, gdy zmienia się stan programu (jak Idle, Praca, PendingStop itp.), To tylko ta właściwość stanu jest używana w procedurach obsługi CanExecute. Nadal nie działa (choć zgadzam się, że powinien). BTW, idź i sprawdź implementację ICommand, znajduje się w artykule, o którym wcześniej wspomniałem, rysunek 3. – dzs

+0

Tak, to naprawdę zależy od tego, w jaki sposób ICommand został wdrożony. Zaktualizowałem swoją odpowiedź, opisując, w jaki sposób mogę ponownie zapytać CanExecute w Prism. Spojrzę na artykuł, który śledzisz. –

+0

Czy jest coś, co można zrobić przy wykonywaniu InvalidateRequerySuggested() w wątku innym niż UI?Spróbuj wywołać funkcję Dispatcher, aby wywołać ją w wątku interfejsu użytkownika. –

Powiązane problemy