Commands

Youtube Tutorials: Commands Part I and Commands Part II

Commands enable a bound method from the ViewModel to be executed from a View element, like a button. You can add an execution validation if the UI element should be shown as disabled for preventing the execution (e.g. you have to enter data first to execute a save command).

A possible implementation of a application wide Command base class could be the following:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
using System;
using System.Windows.Input;
namespace StandUpMate.Command
{
    public class DelegateCommand : ICommand
    {
        public Action CommandAction { get; set; }
        public Func<bool> CanExecuteFunc { get; set; }

        public void Execute(object parameter)
        {
            CommandAction();
        }

        public bool CanExecute(object parameter)
        {
            return CanExecuteFunc == null || CanExecuteFunc();
        }

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

This can be then used linke in the following example, where I want to open a settings window, but only if it is not already opened yet:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/// <summary>
/// Shows the settings window if not opened yet.
/// </summary>
public ICommand ShowSettingsWindowCommand
{
    get
    {
        return new DelegateCommand
        {
            CanExecuteFunc = () => Application.Current.MainWindow == null 
	                           || Application.Current.MainWindow.IsActive == false,
            CommandAction = () =>
            {
                Application.Current.MainWindow = new MainWindow();
                Application.Current.MainWindow.Show();
            }
        };
    }
}

With CanExecuteFunc I validate if the window is already open. The CommandAction then executes the part to open the window.

This code is from my StandUpMate project.

Commands with multiple parameters

Besides simple binding methods to View elements, you can also process multiple parameters through the command call. To achieve this you have to build a MultiValueConverter to pack the parameters:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/// <summary>
/// Converts multiple command parameters to pass as one.
/// </summary>
public class ArrayMultiValueConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        return values.Clone();
    }
    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

This has to be referenced in your XAML code (App.xaml):

1
2
3
<Application.Resources>
    <u:ArrayMultiValueConverter x:Key="ArrayMultiValueConverter" />
</Application.Resources>

ArrayMultiValueConverter reference in XAML

Now you can send multiple parameters from UI elements with the click of a button:

ArrayMultiValueConverter reference in XAML

This is how you access the parameters in the ViewModel:

ArrayMultiValueConverter reference in XAML