Application-wide commands using MVVM

Most commands are registered per view and available per view model. Some commands (such as commands on a Ribbon or Toolbar) are application-wide. Catel supports both types, and this blog post explains how to use the ICommandManager to work with application-wide commands such as Refresh with a key bound to F5.

Note that this information is based on the latest nightly build, this functionality will be included in Catel 3.9.0

Introduction to CommandManager

There is no generic way to specify application-wide commands in WPF and Silverlight. To overcome this issue, Catel introduces the CommandManager. This manager allows to create commands which are hosted by the CommandManager. The commands on the command manager can be created with input gestures (on both WPF and Silverlight). Once a view model wants to hook into a specific command, it only has to register the view model command with the application-wide command.

Creating application-wide commands

To create application-wide commands, one must resolve the ICommandManager from the DependencyResolver and create the command:

var dependencyResolver = IoCConfiguration.DefaultDependencyResolver;
var commandManager = dependencyResolver.Resolve<ICommandManager>();

commandManager.CreateCommand("Refresh", new InputGesture(Key.F5));

It is recommended to put all the command creation in a single place so they are easily manageable.

Registering a custom command

When a view model wants to use application-wide specific commands, the only thing it has to do is register the command in the CommandManager.

public class CommandSubscribingViewModel : ViewModelBase
    private readonly IMessageService _messageService;

    public CommandSubscribingViewModel(ICommandManager commandManager, IMessageService messageService)
        Argument.IsNotNull(() => commandManager);
        Argument.IsNotNull(() => messageService);

        _messageService = messageService;

        ExampleCommand = new Command(OnExampleCommandExecute);
        commandManager.RegisterCommand("Refresh", ExampleCommand, this);

    public Command ExampleCommand { get; private set; }

    private void OnExampleCommandExecute()
        _messageService.Show("Application-wide command executed");

Using application-wide commands in xaml

To make it easy to bind to application-wide commands, Catel provides the CommandManagerBinding markup extension for WPF and Silverlight. To bind to commands in xaml, use the following code:

<Ribbon catel:StackGrid.ColumnSpan="4">
    <RibbonTab Header="Home" KeyTip="H" >
        <RibbonGroup Header="Example commands">
            <RibbonButton Command="{catel:CommandManagerBinding Refresh}" LargeImageSource="..\Resources\Images\Refresh.png"
                          Label="Refresh" KeyTip="F5" />

As the code shows, the CommandManagerBinding extension automatically resolves the Refresh command from the CommandManager.