views:

235

answers:

2

I'm trying to implement a highly responsive UI for my MVVM application, so I've chosen to have all command handlers automatically execute in a BackgroundWorker so they don't block the UI.

But at the same time, I don't want the user to be able to execute the same command while it is still executing in the background. The solution seems obvious:

  1. When Executed handler is invoked, have the CanExecute handler return false
  2. Start the BackgroundWorker async
  3. When BackgroundWorker finishes, have the CanExecute handler return true again.

Problem is, I need to notify WPF after step 1 and again after step 3 that CanExecute has changed and that it should be required. I know I can do it by calling CommandManager.InvalidateRequerySuggested, but that causes CanExecute handlers of all other commands to be requeried as well. Having a lot of commands, that's not good.

Is there a way to ask for requery of a specific command - i.e. the one that is currently being executed?

TIA

+1  A: 

I think you only need to raise the ICommand.CanExecuteChanged event for these two cases, and the corresponding control should update its IsEnabled state.

gehho
A: 

gehho is right, just raise the CanExecuteChanged event. But honestly, I don't know your implementation, but if your CanExecute predicate is simple, I think it will be hard to notice that wpf is requerying. I can't believe you will notice a performance hit. Have you tested performance? I mean let's say you have 20 ICommands in a ViewModel(which is probably too much) if the ICommand.CanExecute points to a boolean field that you are setting to true and false based on the backgroundworker it should take less than nanoseconds. But if the CanExecute is pointed to a method that evaluates, then it may be longer, but I still doubt it would be noticeable.

But hey, I don't know your implementation.

Jose