Skip to content

Creating Command Clients

Gary edited this page Aug 27, 2014 · 1 revision

Table of Contents

ICommandClient interface

A command client implements the ICommandClient interface, which consists of these methods:

bool CanDoCommand(object commandTag);
void DoCommand(object commandTag);
void UpdateCommand(object commandTag, CommandState commandState);

Both WinForms and WPF use the same ICommandClient interface.

CanDoCommand Method

The CanDoCommand() method simply indicates whether or not the command can be performed, usually considering the current context. It is called in response to application events. When the method returns false, the command is disabled, which is indicated in the UI by graying out menu items and tool strip controls. The method's commandTag argument is the same tag the command was registered with.

Here is an example from the ATF Circuit Editor Sample MasteringCommands class. The main thing to notice is that the current context is used to determine whether or not the command is possible by checking if at least one item is selected. And if there is no current context, the command can't be done either.

public bool CanDoCommand(object commandTag)
{
    bool enabled = false;
    var context = m_contextRegistry.GetActiveContext<CircuitEditingContext>();
    if (context != null)
    {
        ISelectionContext selectionContext = context.As<ISelectionContext>();
        if (CommandTag.CreateMaster.Equals(commandTag))
        {
            enabled = selectionContext.GetLastSelected<Element>() != null; // at least one module selected
        }
        else if (CommandTag.ExpandMaster.Equals(commandTag))
        {
            enabled = selectionContext.GetLastSelected<SubCircuitInstance>() != null; // at least one mastered instance selected
        }
    }

    return enabled;
}

UpdateCommand Method

UpdateCommand()'s purpose is to update the command's CommandState, which contains two properties: the command name and menu item check mark. Application events trigger calling UpdateCommand().

CommandState Name

This is the menu's name, initially specified in the command's CommandInfo when the command was registered. You can change this to reflect the status of the command. For instance, the RecentDocumentCommands component updates this text with a document name:

public virtual void UpdateCommand(object commandTag, CommandState state)
{
    if (commandTag is RecentDocumentInfo)
    {
        RecentDocumentInfo info = (RecentDocumentInfo)commandTag;
        state.Text = info.Uri.LocalPath;
    }
}

CommandState Check Mark

The check mark indicates whether or not to display a check on the command's menu. For example, the ATF Timeline Editor Sample uses this feature to place a check on the Edit > Interval Splitting Mode menu item when this mode is active:

public void UpdateCommand(object commandTag, CommandState commandState)
{
    TimelineDocument document = m_contextRegistry.GetActiveContext<TimelineDocument>();
    if (document == null)
        return;

    if (commandTag is Command)
    {
        switch ((Command)commandTag)
        {
            case Command.ToggleSplitMode:
                commandState.Check = document.SplitManipulator != null ? document.SplitManipulator.Active : false;
                break;
        }
    }
}

DoCommand Method

This method performs the command when the command is triggered by the user selecting the command in the menu or tool strip. Its argument is the command tag with which the command was registered. It may simply call other methods, as in this example from the StandardEditCommands component. This method uses commandTag to determine which command is being done, and switches accordingly:

void ICommandClient.DoCommand(object commandTag)
{
    switch ((StandardCommand)commandTag)
    {
        case StandardCommand.EditCut:
            Cut();
            break;

        case StandardCommand.EditDelete:
            Delete();
            break;

        case StandardCommand.EditCopy:
            Copy();
            break;

        case StandardCommand.EditPaste:
            Paste();
            break;
    }
}

The RecentDocumentCommands component's DoCommand() opens the document associated with the menu item, removing the menu item when the document is invalid:

public virtual void DoCommand(object commandTag)
{
    if (commandTag is RecentDocumentInfo) // recently used file?
    {
        RecentDocumentInfo info = (RecentDocumentInfo)commandTag;
        IDocumentClient client;
        if (m_typeToClientMap.TryGetValue(info.Type, out client))
        {
            IDocument document = m_documentService.OpenExistingDocument(client, info.Uri);
            if (document == null)
                RemoveDocument(info);
        }
    }
}

Note that this example from the ATF Circuit Editor Sample MasteringCommands class uses the current context to perform the command:

public void DoCommand(object commandTag)
{
    var context = m_contextRegistry.GetActiveContext<CircuitEditingContext>();
    if (CommandTag.CreateMaster.Equals(commandTag))
    {
        SubCircuitInstance subCircuitInstance = null;

        var masterContext = context.DomNode.GetRoot().Cast<CircuitEditingContext>();
        ...

Topics in this section

Clone this wiki locally