5.1 Custom Pages & Modern Commanding with Power Fx
Key Takeaways
- Custom Pages converge canvas flexibility with model-driven architecture, rendering responsive, pixel-perfect UX as full pages, center dialog modals, or docked side panes.
- The Modern Command Bar designer enables low-code command authoring across Main Grid, Main Form, Subgrid, and Associated View using Power Fx formulas instead of legacy RibbonDiffXml and JavaScript.
- Power Fx command actions leverage declarative functions including Navigate(), Notify(), Patch(), Confirm(), and direct cloud flow execution via FlowName.Run().
- Contextual command execution utilizes system record objects: Self.Selected.Item for single-row contexts and Self.Selected.AllItems for multi-row grid selections.
- Command Visibility rules evaluate boolean Power Fx expressions dynamically based on record state, user attributes, or field thresholds, replacing complex Ribbon Workbench Enable/Display rules.
Custom Pages & Modern Commanding with Power Fx
Model-driven applications provide a robust, metadata-driven architecture for enterprise business processes. However, complex business scenarios often require pixel-perfect layouts, specialized workflows, composite interactions, and low-code command logic that exceed traditional forms and views. Microsoft Power Platform addresses these demands through Custom Pages and Modern Commanding with Power Fx.
For the PL-200: Microsoft Power Platform Functional Consultant exam, you must master how Custom Pages integrate into the model-driven shell, how to configure responsive layouts, how to author modern command buttons across all grid and form scopes, and how to write Power Fx visibility and action formulas that replace legacy Ribbon Workbench JavaScript customizations.
1. Custom Pages Architecture & Hosting Models
A Custom Page is a specialized, solution-aware page type that brings the authoring experience and pixel-level control of Canvas Apps into Model-Driven Apps. Unlike standalone Canvas apps that run in isolated player containers, Custom Pages operate as first-class citizens within the model-driven React/Fluent UI infrastructure.
+-----------------------------------------------------------------------------------+
| CUSTOM PAGE HOSTING ARCHITECTURES |
| |
| [1. FULL PAGE] [2. CENTER DIALOG MODAL] [3. SIDE PANE] |
| +-------------------------+ +-------------------------+ +--------------------+ |
| | Sitemap Navigation Item | | Host Record (Dimmed) | | Host Record Form | |
| | | | +-----------------+ | | | |
| | Full viewport canvas UX | | | Modal Dialog | | | +----------------+ | |
| | Standalone hub / portal | | | Wizard / Action | | | | Docked Sidebar | | |
| | | | +-----------------+ | | | Helper / Notes | | |
| +-------------------------+ +-------------------------+ +--------------------+ |
+-----------------------------------------------------------------------------------+
The Three Hosting Targets
Custom Pages can be displayed in three distinct presentation modes within a model-driven app:
-
Full Page (Sitemap Navigation):
- The Custom Page is added directly into the model-driven App Navigation (Sitemap) as a primary navigation item.
- Takes over the main content viewport, replacing standard entity grids or dashboards.
- Ideal for executive summary workspaces, complex task dispatchers, or multi-entity data entry portals.
-
Center Dialog Modal:
- Opens programmatically over an active record form or grid as an overlay popup.
- Dimms the background and disables interaction with the host page until the user dismisses the dialog or completes the task.
- Configurable with custom pixel width and height (or percentage of viewport) and an optional header/title bar.
- Ideal for multi-step guided wizards, approvals, document generators, and contextual data capture.
-
Side Pane (Right Docked Pane):
- Opens docked on the right side of the screen alongside the active record or view.
- Allows users to interact simultaneously with both the host form and the custom page.
- Ideal for AI copilot assistants, real-time calculation scratchpads, activity timelines, or knowledge base article lookups.
Programmatic Navigation to Custom Pages
Custom pages are invoked from modern command bar buttons or canvas controls using the Power Fx Navigate() function, or via client API using Xrm.Navigation.navigateTo:
// Power Fx Command Button Action to open Custom Page in Center Dialog
Navigate(
cr123_project_wizard_page,
PageType.CustomPage,
{
recordId: Self.Selected.Item.cr123_projectid,
entityName: "cr123_project"
},
{
target: 1, // 0 = Full Page, 1 = Center Dialog, 2 = Side Pane
width: 800, // Dialog width in pixels
height: 600, // Dialog height in pixels
title: "Project Setup Wizard"
}
)
Responsive Design Requirements for Custom Pages
To ensure custom pages scale fluidly across desktop monitors, tablets, and side pane widths, developers must adhere to strict responsive design principles:
- Scale to Fit Must Be Disabled: In App Settings > Display, Scale to fit and Lock aspect ratio must be turned OFF.
- Auto-Layout Containers: All UI controls must be placed inside Horizontal (
Container (horizontal)) and Vertical (Container (vertical)) containers. - Dynamic Sizing: Controls use relative sizing properties such as
Parent.Width,Parent.Height, or container flexible width (Fill portions) rather than hardcoded X/Y coordinates.
2. Modern Commanding with Power Fx Overview
Historically, customizing model-driven command bars required editing XML schemas (RibbonDiffXml), managing JavaScript web resources, utilizing third-party tools like Ribbon Workbench, and writing complex DOM or Client API scripts. Modern Commanding replaces this legacy pipeline with a low-code, declarative authoring canvas powered by Power Fx.
+-----------------------------------------------------------------------------------+
| MODERN COMMANDING ARCHITECTURAL PIPELINE |
| |
| [Modern App Designer] ---> Select Table ---> [Edit Command Bar] |
| | |
| +--------------------+---------------------------+-----------------------+ |
| | | | | |
| v v v v |
| [Main Grid] [Main Form] [Subgrid] [Associated] |
| (Table Views) (Single Record) (Child Grid) (Related View) |
| | | | | |
| +--------------------+---------------------------+-----------------------+ |
| | |
| v |
| [POWER FX COMMAND COMPONENT LIBRARY] |
| - Action Formula: OnSelect = Patch(...) |
| - Visibility Formula: Visible = Record.State = Active |
+-----------------------------------------------------------------------------------+
The Four Command Bar Scopes
When editing a table's command bar in the modern app designer, consultants can target four discrete UI locations:
- Main Grid: Displayed at the top of the full-page table view. Actions can execute on zero selected records (e.g., "Export Summary") or on multiple selected rows (e.g., "Batch Assign").
- Main Form: Displayed at the top of an open individual entity record. Actions execute in the context of the active row.
- Subgrid: Displayed directly above a related records list embedded inside a main form. Actions execute on related child items.
- Associated View: Displayed when navigating to the dedicated related records grid from the form's 'Related' navigation tab.
[!NOTE] Component Library Under the Hood: When you customize a command bar using Power Fx for the first time on a table, Dataverse automatically generates a solution-aware Component Library named after the table (e.g.,
cr123_OrderCommandLibrary). This library stores all the Power Fx formulas, custom icons, and parameter bindings.
3. Power Fx Command Formulas & Context Objects
Modern commanding exposes contextual system variables that allow command buttons to read form state, inspect selected records, and execute data operations.
Record Context Objects
| Context Variable | Scope Availability | Data Type | Description |
|---|---|---|---|
Self.Selected.Item | Main Form, Single Grid Selection | Record | Returns the record object of the currently open or selected row, granting direct access to all column attributes. |
Self.Selected.AllItems | Main Grid, Subgrid, Associated View | Table | Returns a table/collection of all currently selected rows in a multi-select grid. |
Self.Selected.Unsaved | Main Form | Boolean | Returns true if the user has modified fields on the active form but has not yet saved the record. |
+-----------------------------------------------------------------------------------+
| CONTEXT OBJECT RESOLUTION WORKFLOW |
| |
| [Main Form Opened: Order #1042] |
| | |
| +---> Self.Selected.Item.'Total Amount' = $45,000 |
| +---> Self.Selected.Unsaved = false |
| |
| [Main Grid: 3 Accounts Checked] |
| | |
| +---> Self.Selected.AllItems = [Account A, Account B, Account C] |
| +---> ForAll(Self.Selected.AllItems, Patch(Accounts, ThisRecord, ...)) |
+-----------------------------------------------------------------------------------+
Common Power Fx Command Action Patterns
1. Direct Data Patching & User Notification
Update columns directly without navigating away and display modern banner notifications:
// Mark active record as Approved and notify user
Patch(
'Purchase Orders',
Self.Selected.Item,
{
'Approval Status': 'Approval Status (Purchase Orders)'.Approved,
'Approved Date': Now(),
'Approved By': User().Email
}
);
Notify("Purchase Order successfully approved.", NotificationType.Success, 4000)
2. Triggering an Instant Power Automate Cloud Flow
Execute automated business logic directly from a command button:
// Trigger Cloud Flow passing current record GUID and user email
'GenerateInvoicePDF-Flow'.Run(
Self.Selected.Item.cr123_invoiceid,
User().Email
);
Notify("Invoice PDF generation has been queued. You will receive an email shortly.", NotificationType.Information)
3. Modal User Confirmation Dialog
Prompt the operator for explicit confirmation before executing irreversible or destructive actions:
// Prompt user with native confirmation modal
If(
Confirm("Are you sure you want to cancel this reservation? A cancellation fee may apply.", { Title: "Confirm Cancellation" }),
Patch('Flight Reservations', Self.Selected.Item, { Status: 'Status (Flight Reservations)'.Cancelled });
Notify("Reservation cancelled.", NotificationType.Warning)
)
4. Batch Operations on Multi-Select Grid Rows
Iterate across multiple selected rows in a Main Grid or Subgrid:
// Batch update priority for all selected work orders
ForAll(
Self.Selected.AllItems,
Patch(
'Work Orders',
ThisRecord,
{ Priority: 'Priority (Work Orders)'.High }
)
);
Notify(Concatenate(Text(CountRows(Self.Selected.AllItems)), " work orders updated to High Priority."), NotificationType.Success)
4. Dynamic Visibility Rules with Power Fx
In classic model-driven apps, controlling button visibility required defining complex EnableRules and DisplayRules in XML. Modern commanding replaces this with a single Visible property evaluated as a Boolean Power Fx expression (true or false).
+-----------------------------------------------------------------------------------+
| DYNAMIC VISIBILITY EVALUATION LOGIC |
| |
| [Command Button: "Approve Discount"] |
| | |
| v |
| [Evaluate Power Fx Visible Formula] |
| | |
| +---> Rule 1: Record status is 'Pending Review' |
| +---> Rule 2: Discount requested > 15% |
| +---> Rule 3: Current user is a Sales Manager (or specific email/role) |
| | |
| v |
| [Result = TRUE] ---> Button rendered on Command Bar |
| [Result = FALSE] ---> Button hidden automatically in real-time |
+-----------------------------------------------------------------------------------+
Visibility Formula Examples
-
Visibility by Record State & Threshold:
// Visible only if order is submitted and total exceeds $10,000 Self.Selected.Item.statuscode = 'Status Reason (Orders)'.Submitted && Self.Selected.Item.'Total Amount' > 10000 -
Visibility by Multi-Select Count:
// Visible on Main Grid only when between 1 and 20 records are selected CountRows(Self.Selected.AllItems) >= 1 && CountRows(Self.Selected.AllItems) <= 20 -
Visibility by User Context:
// Visible only if current user is the record owner or lead manager Self.Selected.Item.Owner.Email = User().Email || User().Email = "finance-approvals@contoso.com"
[!IMPORTANT] Real-Time Visibility Updates: Power Fx visibility formulas on Main Forms re-evaluate automatically as users edit field values on the form—even before saving—allowing dynamic command bar adjustments during active data entry.
5. Modern Commanding vs. Classic Ribbon Customization
Understanding the architectural differences between modern commanding and classic ribbon customization is critical for both the PL-200 exam and enterprise solution migration.
| Capability / Feature | Modern Commanding (Power Fx) | Classic Ribbon Customization (RibbonDiffXml) |
|---|---|---|
| Authoring Interface | Integrated Modern App Designer | Ribbon Workbench (Third-party tool) or raw XML |
| Logic Language | Power Fx (Declarative Low-Code) | JavaScript (Imperative Client API / DOM) |
| Visibility Definition | Single Boolean Power Fx Formula | Complex XML EnableRules & DisplayRules |
| Cloud Flow Integration | Direct execution via FlowName.Run() | Requires custom JavaScript fetch() / Web API |
| Context Access | Native Self.Selected objects | PrimaryControl, SelectedControlSelectedItemIds |
| Solution Packaging | Solution-aware Component Library | Table XML Customizations (customizations.xml) |
| Custom Pages Hosting | Native Navigate(CustomPage, ...) | Requires Xrm.Navigation.navigateTo scripts |
| Deployment Simplicity | Native solution export/import | High risk of XML merge conflicts and layer locks |
A functional consultant needs to design a guided multi-step return merchandise authorization (RMA) wizard inside a model-driven app. The wizard must open from a command button on the Account form, overlay the center of the screen as a modal dialog with a custom width and height, pass the active Account GUID to the wizard, and prevent interaction with the underlying form until closed. How should the consultant implement this requirement?
A company requires a bulk 'Reassign Territory' button on the Main Grid of the Leads table in a model-driven app. The button should only appear when the user selects at least one lead but no more than 25 leads simultaneously. When clicked, it must execute a Power Automate flow for every selected lead. Which combination of Power Fx formulas should the consultant configure on the modern command button?
A business analyst wants a 'Fast-Track Discount' button on the Opportunity Main Form command bar. The button must only be visible if the Opportunity Estimated Value is greater than $50,000 and the Status Reason is 'In Progress'. Which modern commanding formula correctly achieves this visibility requirement?
An enterprise organization is migrating legacy model-driven app customizations to modern Power Platform architecture. The existing solution contains over 40 custom command buttons authored using Ribbon Workbench, XML EnableRules, and JavaScript Web Resources. What is a primary technical advantage of refactoring these buttons to Modern Commanding with Power Fx?