2010-03-23 2 views
3

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

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

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

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

Есть ли способ запросить информацию о конкретной команде - то есть той, которая в настоящее время выполняется?

ТИА

ответ

6

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

1

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

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

1

Использовать MVVM Helper's `DelegatingCommand ', который предоставляет команду RaiseCanExecuteChanged() для команды.

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