CanExecute Logic for DelegateCommand

c#, command, entity-framework, prism, wpf

Solution

As it already was mentioned, this is intended behavior of `DelagateCommand`, not a bug. `DelegateCommand` doesn't raise `CanExecuteChanged` event automatically, you have to raise that event manually by calling `RaiseCanExecuteChanged` when appropriate. Whereas `RelayCommand` relays on `CommandManager.RequerySuggested` event for that. This event is raised every time the user clicks somewhere or presses a button.

For situations when it is not very convenient or there is no appropriate place for calling `RaiseCanExecuteChanged` (like in your scenario you have to subscribe to `PropertyChanged` event on the model, etc) I have created the following simple wrapper that ensures that the `CanExecute` method of the wrapped command is executed automatically on `CommandManager.RequerySuggested` event:

public class AutoCanExecuteCommandWrapper : ICommand
{
    public ICommand WrappedCommand { get; private set; }

    public AutoCanExecuteCommandWrapper(ICommand wrappedCommand)
    {
        if (wrappedCommand == null) 
        {
            throw new ArgumentNullException("wrappedCommand");
        }

        WrappedCommand = wrappedCommand;
    }

    public void Execute(object parameter)
    {
        WrappedCommand.Execute(parameter);
    }

    public bool CanExecute(object parameter)
    {
        return WrappedCommand.CanExecute(parameter);
    }

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }
}

You can use it like this:

DelegateSaveCommand = new AutoCanExecuteCommandWrapper(new DelegateCommand(Save, CanSaveDelegate));

Problem

Update: The focus became MVVM instead of the actual question so I'm updating it. I'm having a problem with `CanExecute` for `DelegateCommand`. It doesn't update before I call `RaiseCanExecuteChanged`, is this the desired behavior? I uploaded a simple sample project reproducing this problem here : http://dl.dropbox.com/u/39657172/DelegateCommandProblem.zip The problem is this, I have two `Buttons` like this. One is Binding `Command` to a `RelayCommand` implementation and the other is binding to the Prism implementation of `DelegateCommand` ``` <Button Command="{Binding DelegateSaveCommand}"/> <Button Command="{Binding RelaySaveCommand}"/> ``` The ViewModel `ICommands` ``` DelegateSaveCommand = new DelegateCommand(Save, CanSaveDelegate); RelaySaveCommand = new RelayCommand(param => Save(), param => CanSaveRelay); ``` and the `CanExecute` method/predicate ``` public bool CanSaveDelegate() { return HasChanges; } public bool CanSaveRelay { get { return HasChanges; } } ``` Both are using the property `HasChanges`. When `HasChanges` is updated, only the `CanSaveRelay` updates. Is this the way it's meant to be?

Original source

Related problems