Как работает CommandManager.RequerySuggested? - PullRequest
36 голосов
/ 04 мая 2010

MSDN только утверждает, что

Происходит, когда CommandManager обнаруживает условия, которые могут изменить способность выполнения команды.

Однако я не могу найти никаких следов того, как это работает, что я должен знать / избегать и т.д. ... Он просто слушает ввод? (т. е. движение мыши, нажатие клавиш и т. д.)

Ответы [ 2 ]

46 голосов
/ 04 мая 2010

Я не могу точно сказать, какие события CommandManager слушает. Однако я могу вам сказать, что вы должны быть осторожным при использовании CommandManager в связи с асинхронными операциями . У меня была следующая проблема, когда я использовал CommandManager в моих ICommand реализациях:

У меня была кнопка, привязанная к ICommand, которая запускала асинхронную операцию, которая увеличивала значение. Теперь кнопка / ICommand должна быть отключена (т. Е. Ее метод CanExecute() должен возвращать false), если значение достигло определенного предела. Проблема заключалась в следующем: CommandManager вызвал метод my CanExecute() сразу после нажатия кнопки и начала асинхронной операции. Эта асинхронная операция не заняла много времени, но была достаточно длинной, чтобы получить результат после проверки CommandManager, так что проверка предела в CanExecute() была выполнена с использованием старого значения. Поэтому кнопка оставалась включенной, хотя лимит был фактически достигнут. Самое смешное, что после того, как вы щелкнули в любом месте пользовательского интерфейса, кнопка теперь отключилась, потому что CommandManager снова проверил ICommand, и теперь новое значение было проверено на соответствие пределу. На самом деле, я думаю, что CommandManager ждал около 50 мс после нажатия кнопки, пока не выполнил проверку ICommand, но я не совсем уверен в этом.

Моим решением было заставить CommandManager снова проверить ICommand, вызвав метод CommandManager.InvalidateRequerySuggested в моей ViewModel сразу после получения результата асинхронной операции.
Обновление: Обратите внимание, что этот метод должен вызываться в потоке пользовательского интерфейса, иначе он не будет иметь никакого эффекта! (спасибо midspace за этот комментарий)

4 голосов
/ 28 апреля 2014

В этом случае .NET Reference Source - ваш друг. Хотя он плохо прокомментирован, вы все же можете получить некоторые идеи о внутренней обработке.

Во внутреннем CommandDevice классе вы найдете метод PostProcessInput, который вызывает InvalidateRequerySuggested. Название этого метода позволяет предположить, что метод InvalidateRequerySuggested вызывается при каждом входном событии. Я уверен, что есть дальнейшая обработка и фильтрация, чтобы ваш метод CanExecute фактически не вызывался при каждом вызове InvalidateRequerySuggested.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...