Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 4 Next »

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 part of the documentation explains how to use the ICommandManager to work with application-wide commands such as Refresh with a key bound to F5.

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" />
		</RibbonGroup>
	</RibbonTab>
</Ribbon>

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

Command containers

When implementing a ribbon or any menu structure inside an application can result in a very complex view model containing all the commands. Catel solves this issue by implementing so-called command containers. These are containers that have only 1 purpose: contain a command so the logic can easily be viewed / edited and the commands will be available during the whole lifetime of the app. Internally command containers use the ICommandManager to register commands, so the ICommandManager is still responsible for the commands.

Creating a command container

Creating a command container is very simple. It can be done by creating a class deriving from CommandContainerBase as shown in the example below:

public class ApplicationAboutCommandContainer : CommandContainerBase
{
	private readonly IAboutService _aboutService;

	public ApplicationAboutCommandContainer(ICommandManager commandManager, IAboutService aboutService)
		: base(Commands.Application.About, commandManager)
	{
		Argument.IsNotNull(() => aboutService);

		_aboutService = aboutService;
	}

	protected override Execute(object parameter)
	{
		_aboutService.ShowAbout();
	}
}

As you can see the implementation is very clean and won't pollute any other view models.

Registering a command container

To make it very easy to register new commands, Catel uses naming conventions. 

 

  • No labels