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
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)
.
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
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:
// 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
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.
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:
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!" );
}
);
Context menus do not currently support child commands.