Table of Contents

Working with Commands

This framework uses the command pattern for global commands that can be mapped to menu items, tool bar items, or keyboard shortcuts. A command consists of a command definition that define the command and of a command handler that executes the command. The command definitions must be exported via the CommandDefinitionAttribute, the command handlers by the CommandHandlerAttribute.

Create a Command

This example creates a command to initialize a station module.

[CommandDefinition]
public class InitializeStationCommandDefinition : CommandDefinition
{
    private static readonly ITranslation Text = ...
    private static readonly ITranslation ToolTip = ...

    public override string Name => "Modules.InitializeRecursive";

    public override string Text => Text.Translated;

    public override string ToolTip => ToolTip.Translated;

    public override Uri IconSource { get; } = new Uri(...);
}

Run Commands Asynchronous

After running a command in another task, the Update method should be called, to update the command. This can cause some threading problems.
So you have to continue with invocation of the event.

Example: Execute command asynchronous

[CommandHandler]
public class InitializeStationCommandHandler : CommandHandlerBase<InitializeStationCommandDefinition>
{
    private Task _task;

    public override Task Run(Command command)
    {
        _task = Task.Run(() => ExecuteYourLonagRunningCode);
        _task.ContinueWith((t) => Application.Current.Dispatcher.Invoke(CommandManager.InvalidateRequerySuggested));
        return _task.
    }

    public override void Update(Command command)
    {
        // Disable command while running.
        command.Enabled = _task == null || _task.Status != TaskStatus.Running;
    }
}

Command Lists

Dynamic lists of commands can be created, for example, to add a menu item for each current open document. Therefor the command definition must inherit from CommandListDefinition. The command handler must implement the ICommandListHandler<TCommandDefinition> interface.

This example adds three elements to the command list.

[CommandHandler]
internal class ListCommandHandler : ICommandListHandler<ListCommandDefinition>
{
    public void Populate(Command command, List<Command> commands)
    {
        for (int i = 1; i <= 3; i++)
        {
            commands.Add(
                new Command(command.CommandDefinition, null)
                {
                    Text = $"Item {i}",
                    // Store context information in the Tag property
                    Tag = i,
                });
        }
    }

    public Task Run(Command command)
    {
        // Get context from the Tag property
        int context = (int)command.Tag;
    }
}

Extend a Command Handler

To extend an existing command handler, inherit it and export it.

Example: Extend a command handler

[CommandHandler]
public class ExtendedCommandHandler : BaseCommandHandler
{
    private readonly IUserManager _userManager;

    [ImportingConstructor]
    public ExtendedCommandHandler(IUserManager userManager)
        : base(userManager)
    {
        _userManager = userManager;
    }

    public override void Update(Command command)
    {
        base.Update(command);
        command.Enabled = _userManager.CurrentUser.HasPermission(...);
    }
}