MVVM – Commands

Make it So, Number One

In this post, I’m going to look at a couple of ways to use commands to improve the operation of the StaffManager demo application.

The ICommand interface contains three elements

  • Execute – an action to invoke when the command is triggered
  • CanExecute – an optional rule to check whether the command is currently enabled
  • CanExecuteChanged – an event that is fired to tell anything bound to the command to re-evaluate the CanExecute function

MVVMLight has its own implementation of ICommand – RelayCommand, along with a second version that takes a typed parameter. One important note is to avoid using the WPF specific version of these commands, as they reference the old style CommandManager object – CanExecute checks are handled in the background, and can be triggered for all defined commands at any time, perhaps even after each key press or mouse click. Use the version in namespace GalaSoft.MvvmLight.Command, rather then GalaSoft.MvvmLight.CommandWPF. This does requires you to call RaiseCanExecuteChanged() manually as required though.

A common way of handing CanExecute is …

    public MyViewModel()
        DoSomethingCommand = new RelayCommand(() => OnDoSomething(), () => IntProperty > 10); 

    public RelayCommand DoSomethingCommand { get; }

    private void OnDoSomething()

    private int _intProperty

    public int IntProperty
        get { return _intProperty; }
        set { 
                if (Set(nameof(IntProperty), ref _intProperty, value);

… where DoSomethingCommand can only be executed when IntProperty is greater than 10.

However, I believe that this construct is flawed. The IntProperty setter should have no knowledge of how that property is being used. Also, what happens when your command’s CanExecute depends on the state of another object, even one that you don’t have the source code for.

To that end, I’ve created perRelayCommandExtender – a helper class for RelayCommands, that allows a command to observe both properties and observable collections (triggering whenever the collection is updated), in any class. The methods each return the command instance, allowing calls to be chained if the command depends on multiple conditions. Note that if you are observing an object outside of the current ViewModel then you have to be careful to prevent potential memory leaks. ObservesExternalProperty() uses perWeakPropertyChangedEventHandler as discussed in my previous post. Otherwise, if the observed property is in the same ViewModel as owns the command, then we don’t have to be so careful about potential memory leaks. ObservesInternalProperty() just uses a standard PropertyChanged event handler.

It is now possible to write a complex CanExecute function containing multiple clauses, with all the logic in one place. e.g.

    DoSomethingCommand = new RelayCommand(()=> OnDoSomething,
                                          ()=> IntProperty > 10
                                               && SomeItem.BoolProperty 
                                               && ItemList.Any())
                                .ObservesInternalProperty(this, nameof(IntProperty))
                                .ObservesExternalProperty(SomeItem, nameof(SomeItem.BoolProperty))

Async Commands

A standard RelayCommand is fine when the command calls a quick piece of functionality, but what about when the command triggers a long running operation, such as a call to the data access layer, or any other functionality using the async / await model. In the previous post, the loaded command was declared as …

    LoadDataCommand = new RelayCommand(async () => await OnLoadData().ConfigureAwait(false));

… but that looks like a lot of potentially duplicated code. It would also be nice to have the command automatically disable itself while the long running task is executing. To provide this functionality, I’ve created perRelayCommandAsync in the ViewModel library.

    public class perRelayCommandAsync : perViewModelBase, ICommand
        private readonly Func<Task> _execute;
        private readonly Func<bool> _canExecute;

        public perRelayCommandAsync(Func<Task> execute) : this(execute, null) { }

        public perRelayCommandAsync(Func<Task> execute, Func<bool> canExecute)
            if (execute == null)
                throw new ArgumentNullException(nameof(execute));

            _execute = execute;
            _canExecute = canExecute;

        private bool _isExecuting;

        public bool IsExecuting
            get { return _isExecuting; }
            set { 
                    if (Set(nameof(IsExecuting), ref _isExecuting, value))

        public event EventHandler CanExecuteChanged;

        public bool CanExecute(object parameter) => !IsExecuting 
                                                    && (_canExecute == null || _canExecute());

        public async void Execute(object parameter)
            if (!CanExecute(parameter))

            IsExecuting = true;
            await _execute().ConfigureAwait(true);
            IsExecuting = false;

        public void RaiseCanExecuteChanged() => CanExecuteChanged?.Invoke(this, EventArgs.Empty);

So now the commands within the StaffManager application can be declared as …

    LoadDataCommand = new perRelayCommandAsync(OnLoadData);

    AddPersonCommand = new RelayCommand(OnAddPerson);

    DeletePersonCommand = new RelayCommand(OnDeletePerson, () => SelectedPersonVm != null)
        .ObservesProperty(this, nameof(SelectedPersonVm));

    ListSelectedPeopleCommand = new RelayCommand(OnListSelectedPeople, ()=>_personVmList.Any())

Note that the command properties are still defined as just ICommand, as none of the RelayCommand specific functionality is exposed outside of the ViewModel.

Automating Commands

Using buttons to fire off a command is fine for the AddPerson, DeletePerson and ListSelectedPeople command, but it’s not ideal for loading the Person items from the data store. It would be nice to have that functionality called automatically once the View is created and active. That state is indicated by the Loaded event of the View. You could write something like this in MainView.Xaml.cs …

    public MainView()
        DataContext = SimpleIoc.Default.GetInstance<MainViewModel>();
        Loaded += (s, e) => (DataContext as MainViewModel).LoadDataCommand.Execute(null);

… but that promotes very tight coupling between the View and ViewModel classes – not the MVVM way.

These is a better construct though. A combination of the Expression Blend libraries and MVVMLight provides a MVVM pure method to call a bound command, when an event is fired in the View.

<Window x:Class="StaffManager.MainView"

        <i:EventTrigger EventName="Loaded">
            <cmd:EventToCommand Command="{Binding LoadDataCommand}" />

In order for this to work properly, the View’s constructor must be changed slightly – the DataContext must be set before calling InitializeComponent().

    public MainView()
        DataContext = SimpleIoc.Default.GetInstance<MainViewModel>();

If you really need the event’s argument inside the ViewModel, EventToCommand has a PassEventArgsToCommand property. In that case, the command should be defined as RelayCommand<T>, where T is the type of the event argument.

In my next post, I’ll take a short break from MVVM to look at WPF Behaviors.

Don’t forget that all of the code samples for this blog are available on Github, along with my own personal C# / WPF library.

Leave a Reply

Your email address will not be published. Required fields are marked *