Let’s keep it simple – SimpleCommand

Let’s keep it simple – SimpleCommand

Another important part of the MVVM (Model-View-ViewModel) pattern is the allowing the View to request actions in the ViewModel.  We will achieve this with the ICommand Interface.

You can implement many single-purpose classes that implement ICommand, but as a good friend once told me, if you want to find the easy way to do something, ask a lazy person to do it twice.

I like to create a SimpleCommand that implements ICommand, and accepts an Action in the constructor.

public class SimpleCommand : ICommand
{
    public event EventHandler CanExecuteChanged;
 
    private bool _canExecute=true;
    private Action<object> _method = null;
 
    public SimpleCommand(Action<object> method)
    {
        _method = method;
    }
 
    public void setCanExecute(bool canExecute)
    {
        _canExecute = canExecute;
        CanExecuteChanged?.Invoke(this,null);
    }
 
    public bool CanExecute(object parameter)
    {
        return _canExecute;
    }
 
    public void Execute(object parameter)
    {
        _method(parameter);
    }
}

With this SimpleCommand, the CanExecute state is manually set via the setCanExecute method, but you can easily pass a predicate in the constructor to validate CanExecute as well.  Keep in mind, this value should be very inexpensive or better yet cached, as some MVVM frameworks will exhaustively call the CanExecute method to see if the Command has changed states.

You can also extend the constructor to accept a default state for CanExecute, if that is desirable.

Add one of these commands to your ViewModel.

private SimpleCommand _simpleMessageCommand = null;
public SimpleCommand SimpleMessageCommand
{
    get
    {
        if(_simpleMessageCommand ==null)
        {
            _simpleMessageCommand = new SimpleCommand((x) => Message = x as string);
        }
    return _simpleMessageCommand;
    }
}

In this example Message sets a message to the Simple view

private string _message = "Hello World!";
public string Message
{
    get => _message;
    set => setBackingField(ref _message, value);
}

Most of the UI elements you are used to using, with Events, will have Dependency Properties that accept commands to be used in-place of the events.

For instance a button has a Command property that can replace the click event.

Bind to the Command. If you need to pass a parameter you can pass that in the Command’s associated Parameter property; or for advanced data bind to the Parameter.  The button will be enabled or disabled based on the CanExecute state of the Command.

<Button Content="Say 'Button Pressed'" Command="{Binding SimpleMessageCommand}" CommandParameter="Button Pressed"/>

Here is a simple view at startup.


Pressing the Say ‘Button Pressed’ Button, which is connected to our command, will execute the command.  The command will update the message, with the message passed through the parameter.

Leave a Reply