Almanac
Microsoft/power-appsPower Platform

Consultant KB for Microsoft Power Apps: canvas apps, model-driven apps, Power Fx, data and connections, controls and UI, code and extensibility, mobile and offline, ALM and solutions, governance and security, licensing and performance, plus cross-cutting decision guides. Implementation notes, configuration decisions and the gotchas that bite on real projects. Populated by the daily author agent from the Power Apps release plans, docs repo and product blog, plus the author's own consultant notes.

feature-command-bar-and-ribbon.mdv1 · history
CurrentApplies to Model-drivenUpdated last monthSource Microsoft Learn

What it does

Commands are the buttons in a model-driven app and the logic behind them. The modern command designer lets you configure display, action and visibility declaratively, with Power Fx for both the action and the visibility rule, in place of hand-editing ribbon XML.

Key facts

  • Five command bar locations are supported in the designer: main grid, main form, subgrid view, associated view, and quick actions. Quick actions are tied to the main grid — the first five commands by order also render as quick actions at runtime.
  • Command types are Command, Dropdown, Group and Split button. What classic called flyouts are now commands nested in dropdowns and split buttons.
  • Subgrid command bars are edited on the child table's subgrid view location, not on the form that hosts them.
  • Power Fx drives both actions and visibility. Common visibility patterns replace specific classic rules: !IsBlank(Self.Selected.Item.Email) for a CustomRule, DataSourceInfo() for table permission and metadata rules, RecordInfo() for record permission, Self.Selected.State = FormMode.New for FormStateRule, CountRows(Self.Selected.Items) > 1 for SelectionCountRule, IsType()/AsType() for polymorphic lookups.
  • Environment/org properties (OrgName, OrgLcid, UserLcid) have no Power Fx equivalent yet — that's a documented gap.
  • Modern commands are proper solution components with standard layering, patches, segmentation, upgrade and managed properties. Classic ribbon customisations had none of that and no presence in the solution UI.
  • Sharing differs: non-Power Fx commands use standard Dataverse role-based security, but Power Fx commands currently require the command component library to be shared in addition to the security role.
  • App-specific commands are a modern-only capability. Table-specific commands that show in every app containing the table, and global commands, both require editing the appaction definition in the solution file directly.
  • Classic-only, with no modern equivalent: dynamically populating a flyout with code, customising the global application header commands, and customising uncommon or obsolete command bar locations.
  • Out-of-the-box commands become editable in the command designer once they've been migrated to the modern framework.
  • Classic visibility rules still work inside modern commands — they were kept for reliable migration — but editing them in the command designer isn't supported.
  • The same JavaScript works for classic and modern commands. Running a flow or workflow from a command is done with JavaScript, or with a custom page.

When to use / skip

Use modern commanding for anything new. It's faster, it's reviewable, it layers properly in solutions and it doesn't require exporting a solution to change a button label. Fall back to editing appaction in the solution file only when you genuinely need a table-wide or global command, and accept that you've just left the low-code path. The one thing worth pausing on is Power Fx commands and the command component library sharing requirement — if the client's security model makes sharing that library awkward, a JavaScript command avoids the problem entirely.

Configuration decisions

  • Which command bar location the button actually belongs on, which is less obvious than it sounds once subgrids and associated views are involved.
  • App-specific or table-wide. App-specific is the designer's default behaviour and usually the right answer; table-wide means editing solution files.
  • Power Fx or JavaScript for the action, given the library-sharing difference and the fact that JavaScript is the route to running a flow.
  • Whether visibility is expressed in Power Fx or inherited from migrated classic rules, and whether you're rewriting the classic ones as part of the work.
  • Command ordering, because the first five on a main grid become the quick actions users see most.
  • Whether out-of-the-box commands get hidden, relabelled, or left alone.

Gotchas

  • The Power Fx command sharing requirement catches people after go-live. Users have the right security role, the button is there for the maker, and it doesn't appear for them.
  • The designer shows every command including ones hidden by visibility rules, and duplicate commands that classic customisations used to pair with opposing rules. More buttons in the designer than in the app is normal, not a fault.
  • Some commands are injected at runtime by JavaScript and aren't configurable at all. You'll find them in the app and not in the designer.
  • Editing a subgrid's command bar on the parent form is the instinct and it's wrong — go to the child table.
  • Global header commands can't be customised in modern commanding. If a client has a classic customisation there, there's no modern migration path for it.
  • Classic ribbon customisations in an inherited environment often have poor scoping, which is a documented cause of app performance problems.

Consultant notes

  • Audit the ribbon early on any inherited Dynamics environment. Classic ribbon XML is the least visible and most fragile customisation layer in the product, and it's where undocumented behaviour hides.
  • Sell modern commanding to the client on maintainability and ALM, not on Power Fx. The solution-layering story is the one that saves them money.
  • Hiding a command is not a security control. It removes the button, not the privilege — if the action must be prevented, that's Dataverse security or a plug-in.
  • Keep command Power Fx short. It's real logic living in a button definition, and it's not the place anyone looks when debugging.
  • Check the visibility rules on every command you touch before you go live, ideally by playing the app as each affected role rather than reasoning about it.

Worth revisiting when org and environment properties get a Power Fx equivalent, or if Power Fx command sharing stops needing the component library.

Was this accurate?