Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Programatic re-evaluation of MVVM command's "can execute" state

I'm writing a WPF application using the MVVM pattern, based on the following article: WPF Apps With The Model-View-ViewModel Design Pattern

I have two buttons on my View with the buttons' "Command" property bound (with data binding) to a given instance of the RelayCommand class (see "Figure 3 The RelayCommand Class" from the article above). The RelayCommand class has support for checking whether the given command can be executed.

WPF automatically disables buttons whose command cannot be executed.

Each of my commands (in the ViewModel class) start a background operation, and the command cannot be executed again until the background operation is finished. The RelayCommand instances have information whether the background operation is still working or it is finished.

My problem is the following: after pressing the any of the buttons, the buttons automaticaly go disabled (which is OK) because the background operation started and the command cannot be executed until it is finished, but after the operation had finished, the buttons don't go enabled automatically because their command's "can be executed" predicate is not automatically reevaluated. The reevaluation can be manually triggered by having the application loose and regain focus (by pressing ALT+TAB). After doing this trick, the buttons get enabled once again.

How can I programatically reevaluate the buttons' command's "can execute" state?

like image 310
dzs Avatar asked Jun 06 '10 15:06

dzs


1 Answers

You can call InvalidateRequerySuggested on the CommandManager to notify that CanExecute should be re-queried:

CommandManager.InvalidateRequerySuggested();

http://msdn.microsoft.com/en-us/library/system.windows.input.commandmanager.invalidaterequerysuggested.aspx

This does depend on whether the particular ICommand implementation has properly implemented the ICommand.CanExecuteChanged pattern, so YMMV.

Update

For instance, I use Prism which has it's own base implementation ICommand: DelegateCommand. I find that calling RaiseCanExecuteChanged(), on a DelegateCommand in Prism work for me.

Update 2

And make sure that you are calling InvalidateRequerySuggested() on the UI thread. Use the Dispatcher if necessary to make the call.

like image 153
Tim Lloyd Avatar answered Oct 13 '22 06:10

Tim Lloyd