This project has moved and is read-only. For the latest updates, please go here.

RelayCommand in Silverlight (CanExecute issue)

Jul 9, 2012 at 4:40 PM
Edited Jul 9, 2012 at 8:21 PM

Hi guys!

I've started to use MVVM Light Toolkit for Silverlight and faced with a major issue. It really bothers me because it's obvious problem from my perspective but I  I didn't find any solution yet.


Before I start using MVVM Light Toolkit, I used my own ViewModelBase class + RelayCommand and so on.

In order to raise CanExecuteChanged event automatically (smth like in WPF) I created static CommandBindingManager class. It does following work:

1) Every time RelayCommand created, in the constructor of RelayCommand CommandBindingManager.Register(RelayCommand command) is called.

As a result, all commands created in the app, store in the CommandBindingManager

2)In ViewModelBase.RaisePropertyChanged() method I called CommandBindingManager.UpdateCanExecute().

What this method does is call RaiseCanExecute() method on every command that CommandBindingManager stores(on every command in the application)


As a result, if smth is changed in the application -> all commands CanExecute properties are updated too.


Now, I'm using RelayCommand and ViewModelBase from MVVM Light Toolkit. And wondering how you handle CanExecute issue?


Because in real applications situations  happen like this:


GetDataCommand = new RelayCommand(GetData, () => SelectedAccounts != null && SelectedAccounts.Any() && SelectedAccounts.All(entity => entity.Id != Guid.Empty) && SelectedDisplayMode != Mode.None && SelectedPhase != null);

In this case RaiseCanExecute() should be called several times in different properties. It's dublication of code.

What if else one condition will be added to CanExecute and developer forget to add GetDataCommand.RaiseCanExecute() call  to this new property?


or like this:

UndoCommand = new RelayCommand(ManagersHolder.UndoRedoManager.Undo, () => ManagersHolder.UndoRedoManager.CanUndo);


In this case the class where CanUndo method placed even don't know anything about UndoCommand and can't call RaiseCanExecute() method