Building Interactive Canvas Components with Custom Behaviors
Learn how to add OnConfirm and OnCancel behavior properties to your Power Apps components, eliminating workarounds and enabling true UI abstraction.
One of the most requested features for canvas app components was the ability to expose behaviors back to the host app. For years, developers had to hack around this limitation by writing global variables from inside a component or using collections to trigger events externally. The introduction of Behavior Properties (like OnSelect and OnChange) completely changed the game. Components finally became truly interactive units that could communicate their internal events cleanly.
In this guide, we will move past the old workarounds and build a reusable confirmation dialog. You will learn how to design a component's interface, wire up its behavior properties, and consume them in a real-world scenario without breaking encapsulation.
Why Behavior Properties Matter
Before enhanced component properties, if a button inside a component needed to perform an action in the app (like navigating or saving data), you had to resort to brittle patterns:
- Global Variables: The component would
Set(varAction, "confirm")while the app polled or observed this variable. This tightly coupled the component to the app's global state. - Collections: The component would
Collect(EventQueue, {Action: "confirm"})and the app would monitor the collection. Fragile and hard to debug. - Timer Controls: The component would start a timer in the app to simulate a delayed action. Inelegant and a source of timing bugs.
Behavior properties eliminate all of this. They act as a clean output channel. The component announces "the user clicked confirm, run whatever logic the app defines," and the host app independently provides that logic. This is the foundation of a healthy separation of concerns in Power Apps.
Our Scenario: A Reject Order Dialog
Imagine you are building a purchase order approval app. An approver sees a gallery of pending orders. Clicking a "Reject" button should display a confirmation dialog to prevent costly mistakes.
Component Name: cmp_ConfirmDialog
Input Properties (Data):
DialogTitle(Text): "Reject Order"DialogMessage(Text): "Are you sure you want to reject order #ORD-0042?"TargetRecord(Record): The specific order to reject.
Behavior Properties:
OnConfirm: Fires when the user clicks the Confirm button.OnCancel: Fires when the user clicks the Cancel button.
App Variables:
_showConfirmDialog(Boolean): Controls the visibility of the component._confirmTarget(Record): Stores the record passed from the gallery.
Data Source: A SharePoint list or Dataverse table called Orders.
Step 1: Enable Enhanced Component Properties
Before creating the component, ensure the necessary feature toggle is active. Navigate to Settings -> Upcoming features -> Experimental and turn on Enhanced component properties.
In newer environments this feature may already be graduated from experimental. Always verify your settings first.
Step 2: Design the Component
- Go to the Components tab in the Tree View.
- Insert a new component (
New component). Rename it tocmp_ConfirmDialog. - Add the following UI elements:
- A Label for the title.
- A Label for the message.
- A Button labelled
btnConfirm. - A Button labelled
btnCancel.
Step 3: Create the Custom Behavior Properties
Open the Properties pane of the component.
- Create a new custom property:
- Property name:
OnConfirm - Property type: Behavior
- Display name:
OnConfirm
- Property name:
- Create a second custom property:
- Property name:
OnCancel - Property type: Behavior
- Display name:
OnCancel
- Property name:
Step 4: Wire the Buttons Inside the Component
This step is the core of the pattern. Inside the component, the button's OnSelect must explicitly invoke the component's behavior property. This exposes the event to the outside world.
For btnConfirm:
cmp_ConfirmDialog.OnConfirm()
For btnCancel:
cmp_ConfirmDialog.OnCancel()
The component is now complete. It has a clean output interface and knows exactly when to fire each event, but it is completely independent of the app's business logic.
Step 5: Consuming the Component in the App
Now we bring the component into the app and connect the real logic.
-
Go to Screen 1 (or any screen).
-
Insert a Gallery, bind it to the
Ordersdata source. -
Add a Reject button inside the gallery template.
-
On the Reject button's
OnSelect, set the context variables to show the dialog and store the target record.powerfxOnSelect of the Gallery buttonUpdateContext({_showConfirmDialog: true, _confirmTarget: ThisItem}) -
Insert the
cmp_ConfirmDialogcomponent onto the screen (from the Custom ribbon or Insert -> Custom). -
Set the component's input properties:
DialogTitle:"Confirm Rejection"DialogMessage:"Are you sure you want to reject Order " & _confirmTarget.OrderID & "?"TargetRecord:_confirmTargetVisible:_showConfirmDialog
-
Set the component's behavior properties:
-
OnConfirm:powerfxOnConfirm of the component instancePatch(Orders, _confirmTarget, {Status: "Rejected"}); UpdateContext({_showConfirmDialog: false}) -
OnCancel:powerfxOnCancel of the component instanceUpdateContext({_showConfirmDialog: false})
-
Common Mistakes and Troubleshooting
-
"I can't see the behavior property in the property dropdown!" Verify that Enhanced Component Properties is turned on in Settings. Also confirm you created a custom property of type Behavior, not Data or Output.
-
"The code runs automatically when the screen loads!" This usually means you placed the
cmp_ConfirmDialog.OnConfirm()call inside a property that evaluates immediately (likeVisibleorDisplayMode) rather than theOnSelectproperty of the button. -
"My context variables aren't updating!" Context variables (
UpdateContext) are scoped to the screen, not the component. You must define yourOnConfirmandOnCancelformulas on the component instance in the app, not inside the component. The component should contain only the call to its own behavior property. -
"I need to call
OnConfirmconditionally inside the component!" You cannot call a behavior property from inside a function likeIforSwitch— they are imperative commands. If you need conditional logic inside the component (e.g., "if validation passes, fireOnConfirm"), expose multiple behavior properties and let the app handle the condition. Alternatively, set a data property to a validation result and drive the logic from the app side.Conditional Behavior CallsBehavior properties must be the direct result of a user action. You cannot nest them in conditionals inside the component. Keep the component simple and move complex decision logic to the app.
Security, Performance, and Delegation
Behavior properties themselves have no delegation issues, but the formulas you write inside the host app's event handlers must still follow standard Power Apps delegation rules. In the example above, Patch is delegable for most data sources. If you place a Filter inside an OnConfirm handler, ensure it can be delegated.
Using behavior properties encourages a clean architecture where the component is strictly a "view" and the host app handles all "controller" and "model" logic. This makes your code far easier to audit, test, and maintain over time.
Final Thoughts
Behavior properties are not a gimmick. They are the foundation for building professional, enterprise-grade canvas apps. By investing a few minutes to properly encapsulate a custom dialog inside a component with behavior outputs, you dramatically reduce duplication and complexity.
Go back to your existing apps and look for repetitive "Are you sure?" confirmation logic. Build a component for it. Your future self — and every developer who inherits your app — will thank you.
References
- Original source article referenced for the technical concept: Matthew Devaney, Power Apps Component With An OnSelect Property.
- Microsoft Learn: Create a canvas component in Power Apps (see the section on custom properties).
- Microsoft Learn: Work with component properties.
Learn how small coding practices—like using descriptive names, flattening conditions, and simplifying logic—can make your apps easier to update and less error-prone.
Move past the gallery and discover the hidden patterns for validation, navigation, and smart submission handling in your data entry forms.
PowerShell unlocks admin capabilities that the Power Platform admin center simply doesn’t offer—from recovering deleted apps to blocking trial licenses. Here’s how to wield them safely.