Skip to main content

Using Custom Commands

The Custom Commands interface provides a set of commands for customizing menus, creating custom commands, and managing their states in M-Files UI Extensions. The ICommands provides set of tools for developers to customize the user interface, manage commands, and control their visibility and availability within the application.

Managing Commands

note

ICommands is part of IShellFrame interface. To use this interface you have to first obtain instance of the IShellFrame.

Creating a Custom Command

The commands created by the ICommands interface are usually so called Custom Commands which are available only for your UI Extension application.

// Create a new custom command using IShellFrame instance.
const commandId = await shellFrame.Commands.CreateCustomCommand(name);

Controlling the Command visibility

Creating a command does not automatically add the command to the user interface. To do that the SetCommandState method must be used. This method defines the command state (hidden/visible) in specific parts of the user interface:

shellFrame.Commands.SetCommandState( 
commandId, // The ID of the command which state is to be changed
MFiles.MenuLocation.MenuLocation_TopPaneMenu, // The menu location of the change
MFiles.CommandState.CommandState_Hidden // New state of the command in specific location or
);

Executing the Command manually

The Custom command can executed directly using ExecuteCommand, which accepts also optional data parameter.

The data must be serializeable using Structured Cloning Algorithm.

// Execute a new custom command with data parameter
await shellFrame.Commands.ExecuteCommand(commandId, {
someCustomData: 1234
});

Listening and Responding to Custom Commands

User can listen to cuostom command events using MFiles.Event.CustomCommand, which has a callback having parameters (commandId, data).

tip

It is generally recommended to have a single listener function for custom commands to avoid responding to the same command multiple times.


// Listen for the custom commands.
shellFrame.Commands.Events.Register(

// Listen for the CustomCommand events.
MFiles.Event.CustomCommand,

// Each command has ID and optional data provided with it.
( commandId, data ) => {
}
);

Command locations

tip

The commands sample includes practical examples of code that adds commands to different locations.

Commands can be shown in two primary locations: within the context menu (shown when the user right-clicks on something in a listing), and within the main menu.

The context menu

Commands can be added to the context menu which is shown when a user right-clicks on something in a listing. The command may be shown similarly to this:

The command shown in the context menu

// This code should be placed to run when the shell frame is started.

// Create the command.
const commandOneId = await shellFrame.Commands.CreateCustomCommand
(
"My First Command"
);

// Add the command to the bottom of the context menu.
await shellFrame.Commands.AddCustomCommandToMenu
(
commandOneId,
MFiles.MenuLocation.MenuLocation_ContextMenu_Bottom, // Note: context menu
1
);

// Show a message when the command is clicked.
shellFrame.Commands.Events.Register(
MFiles.Event.CustomCommand,
async ( commandId ) => {

// If something other than our command was clicked then die.
if(commandId !== commandOneId)
return;

// Our context menu command was clicked.
await shellFrame.ShowMessage( "My context menu command was clicked." );
}
);

The main menu

tip

The commands sample includes practical examples of code that adds commands to different locations.

Commands can be added to the "main menu", which is located at the top-right of the user interface, as a three-dot icon. Clicking this icon expands the menu and shows commands added to the menu.

note

The main menu is not shown until one or more UI Extensions add commands to this location.

// This code should be placed to run when the shell frame is started.

// Create the command.
const commandOneId = await shellFrame.Commands.CreateCustomCommand
(
"My First Command"
);

// Add the command to the main menu.
await shellFrame.Commands.AddCustomCommandToMenu
(
commandOneId,
MFiles.MenuLocation.MenuLocation_TopPaneMenu, // Note: top pane menu
1
);

// Show a message when the command is clicked.
shellFrame.Commands.Events.Register(
MFiles.Event.CustomCommand,
async ( commandId ) => {

// If something other than our command was clicked then die.
if(commandId !== commandOneId)
return;

// Our context menu command was clicked.
await shellFrame.ShowMessage( "My top menu command was clicked." );
}
);

Child commands

The main menu supports commands with sub-menu commands. This functionality allows you to group commands logically by function within your application:

A main menu command with sub-menu commands

To do this, create the parent command and then call CreateSubMenuItem to create child commands:

// This code should be placed to run when the shell frame is started.

// Create the parent command.
const commandOneId = await shellFrame.Commands.CreateCustomCommand
(
"My First Command"
);

// Add the parent command to the main menu.
const parentMenuItemId = await shellFrame.Commands.AddCustomCommandToMenu
(
commandOneId,
MFiles.MenuLocation.MenuLocation_TopPaneMenu, // Note: top pane menu
1
);

// Create child commands (buttons).
const commandChildOneId = await shellFrame.Commands.CreateCustomCommand
(
"My First Child Command"
);
const commandChildTwoId = await shellFrame.Commands.CreateCustomCommand
(
"My Second Child Command"
);

// Add the child commands to the parent.
await shellFrame.Commands.CreateSubMenuItem( parentMenuItemId, commandChildOneId, 1 );
await shellFrame.Commands.CreateSubMenuItem( parentMenuItemId, commandChildTwoId, 1 );


// Show a message when the command is clicked.
shellFrame.Commands.Events.Register(
MFiles.Event.CustomCommand,
async ( commandId ) => {

// Only react when the child commands are clicked.
if(commandId !== commandChildOneId && commandId !== commandChildTwoId)
return;

// One of the two child commands was clicked.
await shellFrame.ShowMessage( "One of the child commands was clicked!" );
}
);
note

Context menus do not currently support child commands.