Какова реальная задача CanExecuteChanged и CommandManager.RequerySuggested? - PullRequest
35 голосов
/ 09 июля 2011

Я получил следующий код из учебника Джоша Смита по MVVM .

Может кто-нибудь дать краткое объяснение того, что этот код на самом деле делает?не понимают две вещи:

  1. что делает событие CanExecuteChanged?
  2. что делает CommandManager.RequerySuggested?

Приведенный выше кодот RelayCommand класса от здесь .

Ответы [ 2 ]

46 голосов
/ 09 июля 2011
  1. CanExecuteChanged уведомляет любые источники команд (например, Button или MenuItem), связанные с тем ICommand, что значение, возвращаемое CanExecute, изменилось. Источники команд заботятся об этом, потому что они обычно должны соответствующим образом обновить свой статус (например, Button отключится, если CanExecute() вернет false).
  2. Событие CommandManager.RequerySuggested возникает всякий раз, когда CommandManager думает, что что-то изменилось, что повлияет на возможность выполнения команд. Это может быть изменение фокуса, например. Оказывается, это событие часто срабатывает.

Таким образом, в сущности, этот бит кода обеспечивает то, что всякий раз, когда менеджер команд считает, что возможность выполнения команды изменилась, команда вызовет CanExecuteChanged, даже если она на самом деле не изменилась.

Мне на самом деле не нравится этот подход к реализации ICommand.CanExecuteChanged - он ленивый и не совсем надежный. Я предпочитаю гораздо более детальный подход, когда команда предоставляет метод (например, RaiseCanExecuteChanged()), который вы можете вызвать для поднятия CanExecuteChanged, а затем вызываете его в подходящее время из вашей модели представления.

Например, если у вас есть команда, которая удаляет текущего выбранного клиента, он будет иметь обработчик CanExecute(), который возвращает true, только если выбран клиент. Поэтому вы будете звонить RaiseCanExecuteChanged всякий раз, когда выбранный клиент меняется.

5 голосов
/ 09 июля 2011
  • RoutedCommands может автоматически уведомлять, если их CanExecute изменилось, поскольку мы реализуем здесь ICommand, о котором система WPF не знает, мы подключаем их к событию CommandManager RequerySuggested.
  • Теперь это событие довольно часто вызывается системой WPF, когда меняется фокус, редактируется любой элемент управления и т. Д. Следовательно, в свою очередь, CanExecuteChanged повышается. Когда ваша кнопка прослушивает это событие, она будет повторно вызывать CanExecute, чтобы узнать последний статус.

Вот статья , которая может представлять интерес.

...