Возможно ли, чтобы CommandManager запрашивал только определенную команду WPF вместо всех? - PullRequest
3 голосов
/ 23 марта 2010

Я пытаюсь реализовать высокочувствительный пользовательский интерфейс для моего приложения MVVM, поэтому я решил, что все обработчики команд будут автоматически выполняться в BackgroundWorker, чтобы они не блокировали пользовательский интерфейс.

Но в то же время я не хочу, чтобы пользователь мог выполнять ту же команду, пока она выполняется в фоновом режиме. Решение кажется очевидным:

  1. При вызове обработчика Executed обработчик CanExecute возвращает false
  2. Запустить BackgroundWorker асинхронный
  3. Когда BackgroundWorker завершится, обработчик CanExecute снова вернет true.

Проблема в том, что мне нужно уведомить WPF после шага 1 и еще раз после шага 3, что CanExecute изменился и что это необходимо. Я знаю, что могу сделать это, вызвав CommandManager.InvalidateRequerySuggested, но это также вызывает запрос CanExecute обработчиков всех других команд. Имея много команд, это не хорошо.

Есть ли способ запросить конкретную команду, т. Е. Ту, которая выполняется в данный момент?

ТИА

Ответы [ 3 ]

6 голосов
/ 23 марта 2010

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

1 голос
/ 12 декабря 2011

Используйте MVVM Помощник DelegatingCommand, который предоставляет RaiseCanExecuteChanged () для Команды.

Таким образом, вы можете подписаться на событие RunWorkercompleted на BackgroundWorker и, в зависимости от вида регистрируемой работы (возможно, вы можете вернуться как часть Результата), вы вызываете Command.RaiseCanExecuteChanged() из ViewModel.

1 голос
/ 25 марта 2010

gehho прав, просто вызовите событие CanExecuteChanged.Но, честно говоря, я не знаю вашу реализацию, но если ваш предикат CanExecute прост, я думаю, будет трудно заметить, что wpf запрашивает.Я не могу поверить, что вы заметите хит производительности.Вы тестировали производительность?Я имею в виду, скажем, у вас есть 20 ICommands в ViewModel (что, вероятно, слишком много), если ICommand.CanExecute указывает на логическое поле, которое вы устанавливаете в true и false в зависимости от фонового работника, это должно занять меньше наносекунд.Но если CanExecute указывает на метод, который оценивает, то он может быть длиннее, но я все еще сомневаюсь, что это будет заметно.

Но эй, я не знаю вашу реализацию.

...