Modern commanding overview
Commands drive core application behavior for model-driven apps. They are the buttons users interact with when playing apps and the resulting actions performed when a button is selected. Each command is positioned in relation to other commands and bound to a command bar location within the app.
At a high level, command customization fits into the following categories. Various capabilities exist within each category and are covered in more depth throughout modern commanding documentation:
- Display. How the button appears and where it's located in an app. For example, the button's label, icon, and accessibility labels as well as the command bar location and position within a command bar.
- Action. The logic that is executed when a button is selected. For example, creating and updating data or interacting with various controls and pages inside the app.
- Visibility. Logical conditions that specify when a button is visible or hidden to a user. For example, you may want the button visible for some users and hidden for others. Or perhaps the button should only be visible when certain criteria of the data records are satisfied.
Command bar locations
Main grid. This command bar is displayed when using the left-hand navigation of an app to view a full page list of records in this table.
![Command bar on main grid](media/commanddesigner-home-grid-locatioaccount record select the Related tab then select a related table like contacts.
Quick actions. Quick actions are associated with the main grid location. To add or edit commands for both quick actions and main grid locations, select the desired table from within modern app designer, then edit the command bar and choose the main grid location. The first five commands, determined by order, will also be shown as quick actions when playing the app.
Less frequently customized command bar locations are not supported in command designer. See the Global command bar and other ribbons sections for more information on customizing commands for these locations.
Types of commands
- Command. Standard button. Performs an action when selected. Can also be nested in groups within dropdowns and split buttons. Note these were called flyouts in classic commanding.
- Dropdown. Creates a menu where you can organize commands within a group.
- Group. Add titles to groups of commands nested within dropdowns and split buttons.
- Split button. Similar to a dropdown, but has a primary command. When the split button is selected, the action from the primary command is executed. If the expand chevron is selected, the primary command will not be executed. Instead a list will expand to show additional groups, flyouts, and commands.
Key differences between classic and modern commands
Classic commands (formerly known as the ribbon) were not customizable using low code. With code, command customizations were difficult, tedious, and error prone. In order to scale commanding to low code as well as use custom pages to converge canvas and model-driven apps, it was vital to reinvent and rebuild the command infrastructure.
Modern commanding offers many new capabilities and is much simpler to use.
|Supported in model-driven app runtime||Yes||Yes, Additionally supports Power Fx runtime.|
|Customized using||Hand editing XML within solution files or using 3rd party tools. Required time consuming solution export and import operations.||Command designer as well as Dataverse API support.|
|Supports Power Fx.||No||Yes. For actions and visibility.|
|Time required to customize||Slow, error prone.||Fast|
|Reliability and performance||Easy to make mistakes. Bad customization and lack of scoping often impact app performance||Inline error handling prevents mistakes. Power Fx optimized for better runtime performance.|
|Sharing||Standard Dataverse role-based security.||Non-Power Fx commands use standard Dataverse role based security. Power Fx commands currently require the command component library to be shared in addition to having an appropriate security role.|
|Solution and ALM behaviors||Inconsistent and problematic solution layering, no presence in solution interface. Many standard solution behaviors not supported such as patches, segmentation, solution upgrade, managed properties, and many more.||Standard solution layering centrally managed for multiple solution object types within Dataverse. Present in solution interface. All standard solution behaviors supported.|
|Localization||Non-standard||Standardized using export & import translations for the entire solution.|
|Data model||Complex. Optimized for classic ribbons and contain many properties that are no longer needed.||Simple, optimized for today’s model-driven app command bars.|
|Customize out of the box commands||Yes||Commands become editable in command designer once migrated to the modern framework.|
|App specific commands||No||Yes. Using modern command designer ensures commands are only visible within the selected app.|
|Table specific commands that will display in all apps containing the table||Yes||Yes. Requires modifying the
|Global commands that will display for all tables & apps for the specified command bar location||Yes||Yes. Requires modifying the
|Create split buttons, flyouts, and groups||Yes||Yes|
|Dynamically populate a flyout with code||Yes||No. We recommend creating commands declaratively.|
|Customize global application header commands||Yes||No|
|Customize commands for other / uncommon or obsolete command bar locations||Yes||No|
Classic versus modern visibility rule comparison
Classic visibility rules often had a specific rule for each scenario. With Power Fx, a declarative function replaces many classic rules. And it’s much simpler to use.
Note classic visibility rules will also be supported soon within modern commands. However, support for classic rules was needed for reliably migrating classic commands to modern commanding and classic rules customization within command designer isn't supported. We recommend you use Power Fx going forward.
|Use case||Classic Rule||Classic options||Power Fx visible property|
|Show/hide based on table permission||EntityPrivilegeRule||Multiple||DataSourceInfo()|
|Show/hide based on record permission||RecordPrivilegeRule||Multiple||RecordInfo()|
|Reference the control context for primary and related tables||EntityRule||PrimaryEntity. SelectedEntity||Self.Selected|
|Reference the control context||EntityRule||Form. HomePageGrid. SubGridStandard. SubGridAssociated||Self.Selected|
|Table metadata properties||EntityPropertyRule||DataSourceInfo()|
|Show / hide based on form state. For example, show for the create form||FormStateRule||Create. Existing. ReadOnly. Disabled. BulkEdit||Self.Selected.State = FormMode.New|
|Show when > 1 records are selected in a grid||SelectionCountRule||CountRows(Self.Selected.Items) > 1|
|Show / hide for a related table in a polymorphic lookup. For example, check whether the lookup is a user OR a team||CustomRule||PrimaryEntityTypeCode||IsType(), AsType|
|Reference environment properties (Org)||CustomRule||OrgName. OrgLcid. UserLcid||Not currently available|
Frequently asked questions
- Why do I see more commands in the designer than I see in my app?
- Why do I see duplicate commands in the designer?
- This was a common pattern used with classic commands. Both commands would not show up in runtime as they were controlled by visibility rules. The command designer will show all commands, regardless of their visibility rules.
Submit and view feedback for