Программная переоценка команды MVVM "может выполнить"

Я пишу приложение WPF с использованием шаблона MVVM на основе следующей статьи: Приложения WPF с шаблоном проектирования Model-View-ViewModel

У меня есть две кнопки на моем представлении с привязкой свойств кнопок "Command" (с привязкой данных) к данному экземпляру класса RelayCommand (см. "Рисунок 3 Класс RelayCommand" из статьи выше). Класс RelayCommand поддерживает проверку выполнения данной команды.

WPF автоматически отключает кнопки, команда которых не может быть выполнена.

Каждая из моих команд (в классе ViewModel) запускает фоновый режим, и команда не может быть выполнена снова, пока операция фона не будет завершена. В экземплярах RelayCommand есть информация о том, работает ли фоновая операция или она завершена.

Моя проблема заключается в следующем: после нажатия любой из кнопок автоматические кнопки отключены (это нормально), потому что начата фоновая операция, и команда не может быть выполнена до ее завершения, но после завершения операции, кнопки не включаются автоматически, потому что их команда "может быть выполнена" предикат не переоценивается автоматически. Повторная оценка может быть инициирована вручную, если приложение потеряно и восстановление фокуса (нажав ALT + TAB). После выполнения этого трюка кнопки снова активируются.

Как я могу программно пересмотреть команду кнопок "может выполнить" состояние?

Ответ 1

Вы можете вызвать InvalidateRequerySposed в CommandManager, чтобы уведомить, что CanExecute следует повторно запросить:

CommandManager.InvalidateRequerySuggested();

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

Это зависит от того, правильно ли реализована конкретная реализация ICommand шаблона ICommand.CanExecuteChanged, поэтому YMMV.

Обновление

Например, я использую Prism, у которого есть собственная базовая реализация ICommand: DelegateCommand. Я нахожу, что вызов RaiseCanExecuteChanged(), на DelegateCommand в Prism работает для меня.

Обновление 2

И убедитесь, что вы вызываете InvalidateRequerySposed() в потоке пользовательского интерфейса. При необходимости используйте Диспетчер, чтобы сделать звонок.