Skip to content
Learni
Voir tous les tutoriels
Power Platform

Comment développer des contrôles PCF pour Power Apps en 2026

Read in English

Introduction

Power Apps, pilier de la Power Platform Microsoft, permet de créer des applications low-code rapides, mais pour des besoins experts comme des UI customisées haute performance ou des interactions complexes, les contrôles PCF (Power Apps Component Framework) sont indispensables. En 2026, avec l'essor de l'IA et des données massives, les PCF transcendent le low-code en offrant un contrôle total via TypeScript, tout en s'intégrant nativement aux formules Power Fx et aux data sources comme Dataverse ou SharePoint.

Ce tutoriel expert vous guide pas à pas pour développer un contrôle PCF slider personnalisé réactif, l'intégrer dans une app canvas avec des formules avancées gérant la délégation et les collections, puis le déployer en production. Vous apprendrez à éviter les pièges de performance (comme les re-renders inutiles) et à scaler pour des environnements enterprise. À la fin, vos apps Power Apps rivaliseront avec du code natif, boostant productivité et ROI. (142 mots)

Prérequis

  • Node.js 20+ et npm installés (vérifiez avec node -v).
  • Power Apps CLI (PAC CLI) version 1.14+.
  • Visual Studio Code avec extensions Power Platform Tools et TypeScript.
  • Compte Power Apps avec licence Premium (pour Dataverse et PCF).
  • Environnement Power Apps dédié (créé via make.powerapps.com).
  • Connaissances avancées en TypeScript, Power Fx (délégation, variables) et Dataverse.

Installer Power Apps CLI

terminal-install.sh
npm install -g @microsoft/powerapps-cli
pac auth create --environment-id YOUR_ENVIRONMENT_ID
pac pcf init --namespace MonControle --name SliderCustom --template field --description "Slider PCF personnalisé"

Cette commande installe globalement la PAC CLI, authentifie sur votre environnement Power Apps (remplacez YOUR_ENVIRONMENT_ID par l'ID de make.powerapps.com > Environnements), et initialise un projet PCF de type 'field' pour un contrôle réutilisable dans les forms. Le template 'field' est idéal pour les inputs customisés, évitant les pièges des templates 'dataset' plus complexes.

Structure du projet PCF

Une fois initialisé, le projet contient ControlManifest.Input.xml, index.ts, bundle.d.ts et tsconfig.json. Naviguez dans /SliderCustom avec VS Code. Nous allons customiser le slider pour supporter des tooltips dynamiques, des validations en temps réel et des bindings Dataverse, optimisés pour mobile/desktop.

Implémenter le contrôle TypeScript

SliderCustom/index.ts
import {IInputs, IOutputs} from './generated/ManifestTypes';
import * as React from 'react';
import * as ReactDOM from 'react-dom';
import Slider from './Slider';

export class SliderCustom implements ComponentFramework.StandardControl<IInputs, IOutputs> {
  private _container: HTMLDivElement;
  private _notifyOutputChanged: () => void;
  private _value: number;
  private _min: number = 0;
  private _max: number = 100;
  private _context: ComponentFramework.Context<IInputs>;

  public init(context: ComponentFramework.Context<IInputs>, notifyOutputChanged: () => void, state: any, container: HTMLDivElement): void {
    this._container = container;
    this._notifyOutputChanged = notifyOutputChanged;
    this._context = context;
    this._value = context.parameters.sampleProperty.raw || 50;
    this._min = context.parameters.minValue.raw || 0;
    this._max = context.parameters.maxValue.raw || 100;
    ReactDOM.render(React.createElement(Slider, {
      value: this._value,
      min: this._min,
      max: this._max,
      onChange: (val: number) => this.onValueChange(val)
    }), this._container);
  }

  public onValueChange(value: number): void {
    this._value = value;
    this._notifyOutputChanged();
  }

  public getOutputs(): IOutputs {
    return {
      sampleProperty: this._value
    };
  }

  public updateView(context: ComponentFramework.Context<IInputs>): void {
    this._min = context.parameters.minValue.raw || 0;
    this._max = context.parameters.maxValue.raw || 100;
    // Re-render logic
    ReactDOM.unmountComponentAtNode(this._container);
    ReactDOM.render(React.createElement(Slider, {
      value: this._value,
      min: this._min,
      max: this._max,
      onChange: (val: number) => this.onValueChange(val)
    }), this._container);
  }

  public destroy(): void {
    ReactDOM.unmountComponentAtNode(this._container);
  }
}

// Composant React Slider (simplifié)
const Slider: React.FC<{value: number, min: number, max: number, onChange: (val: number) => void}> = ({value, min, max, onChange}) => {
  return (
    <input
      type="range"
      min={min}
      max={max}
      value={value}
      onChange={(e) => onChange(parseInt(e.target.value))}
      style={{width: '100%', height: '8px', borderRadius: '4px'}}
      title={`Valeur: ${value}`}
    />
  );
};

Ce code TypeScript complet implémente un contrôle PCF réactif avec React, gérant les bindings inputs/outputs (sampleProperty pour valeur, minValue/maxValue custom). L'updateView évite les re-renders full en re-mountant seulement si params changent, optimisant perf sur datasets larges. Piège évité : ne pas oublier destroy() pour cleanup mémoire.

Configurer le manifest XML

SliderCustom/ControlManifest.Input.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest>
  <control namespace="MonControle" constructor="SliderCustom" version="0.0.1" display-name-key="Slider_Custom" description-key="Slider PCF personnalisé" control-type="standard" preview-image="/img/Slider.png">
    <data-set name="sampleDataset" display-name-key="Sample_Data_Set" />
    <property name="sampleProperty" display-name-key="Sample_Property" description-key="Sample Property" of-type="SingleLine.Text" usage="bound" required="true" />
    <property name="minValue" display-name-key="Min_Value" description-key="Valeur minimale" of-type="Whole.Number" default-value="0" />
    <property name="maxValue" display-name-key="Max_Value" description-key="Valeur maximale" of-type="Whole.Number" default-value="100" />
    <resources>
      <code path="index.ts" order="1"/>
      <css path="css/SliderCustom.css" order="1" />
      <resx path="strings/SliderCustom.1033.resx" version="1.0.0" />
    </resources>
    <feature-usage>
      <uses-feature name="BoardingRequired" required="true" />
    </feature-usage>
  </control>
</manifest>

Le manifest définit les propriétés bound (sampleProperty à un champ Dataverse) et unbound (min/max), avec dataset pour futures extensions. Ajoutez pour boarding (test en solution). Piège : types of-type doivent matcher Dataverse pour éviter erreurs runtime ; testez toujours en preview.

Build et test du PCF

Exécutez npm run build pour compiler en bundle. Puis pac pcf push --publisher-prefix monprefix pour déployer en environnement dev. Créez une solution unmanaged via make.powerapps.com, ajoutez le PCF à un form Dataverse (ex: table 'Account', champ custom Decimal). Testez en play mode.

Build et push via CLI

terminal-build.sh
cd SliderCustom
npm install
npm run build
pac solution init --publisher-name "Mon Org" --publisher-prefix monorg
pac solution add-reference --path .\Components\MonControle
msbuild /p:configuration=Release
pac solution export --path ./output/SliderCustom.zip
pac pcf push --publisher-prefix monorg

Ce script build le PCF, init une solution, référence le composant, exporte en ZIP et pushe directement. Utilisez msbuild pour Release (optimisé prod). Piège : publisher-prefix doit matcher votre org ; sinon, erreur 401 auth.

Intégrer dans une app Canvas avancée

Créez une app canvas blank sur Dataverse table 'Accounts'. Ajoutez un Form, insérez le PCF Slider sur un champ custom 'Score'. Utilisez Power Fx pour des logiques expertes : collections filtrées, délégation sur >2000 records, variables contextuelles.

Formule Power Fx avec délégation

App/OnVisible_Screen1.pfx
ClearCollect(colAccountsFiltered, Filter(Accounts, 'Created On' >= DateAdd(Today(), -30), Score >= SliderCustom1.Value));
Set(varTotalScore, Sum(colAccountsFiltered, Score));
Set(varDelegationWarning, If(CountRows(colAccountsFiltered) > 2000, "⚠️ Délégation limitée - Ajoutez index sur 'Created On'", "OK"));
UpdateContext({locSliderMin: 0, locSliderMax: 100});

Cette formule OnVisible charge une collection filtrée délégable (Filter sur champs indexés), calcule un sum agrégé et gère warnings délégation. Set/UpdateContext bind au PCF (SliderCustom1.Value). Piège : sans index Dataverse, Filter non délégable → charge tout, crash perf.

Formule OnSelect du Slider avec validation

SliderCustom_OnChange.pfx
If(SliderCustom1.Value < 50, 
  UpdateContext({locStatus: "Bas"}); 
  Patch(Accounts, LookUp(Accounts, AccountId = GUID(Parent.AccountId)), {Score: SliderCustom1.Value}), 
  UpdateContext({locStatus: "Haut"}); 
  Patch(Accounts, LookUp(Accounts, AccountId = GUID(Parent.AccountId)), {Score: SliderCustom1.Value})
);
Refresh(Accounts);
Notify("Score mis à jour: " & SliderCustom1.Value, NotificationType.Success);

OnChange du Slider : conditionnel pour status, Patch délégable sur record parent (via LookUp GUID), Refresh data source. Notify pour UX. Piège : GUID() pour primary key ; sans, Patch échoue silently.

Déploiement en production

Exportez la solution ZIP (PCF + app), importez en prod env via make.powerapps.com > Solutions. Activez le PCF en 'Manage Components'. Partagez l'app avec rôles Azure AD. Pour CI/CD, intégrez à Azure DevOps avec PAC CLI tasks.

Bonnes pratiques

  • Performance : Limitez re-renders PCF avec shouldComponentUpdate ; testez delegation Power Fx via Monitor.
  • Sécurité : Validez inputs PCF côté client/serveur ; utilisez bound properties pour Dataverse Row-Level Security.
  • Responsive : Utilisez context.mode pour détecter canvas/model-driven et ajustez CSS.
  • Versioning : Incrémentez manifest version ; utilisez solutions ALM pour managed/unmanaged.
  • Tests : Implémentez unit tests Jest dans PCF ; boarding pour F5 en dev.

Erreurs courantes à éviter

  • Délégation ignorée : Filter/Sum sur non-délégables (texte long) → timeout ; indexez colonnes Dataverse.
  • Auth PAC CLI : pac auth clear si env switch ; toujours --environment-id précis.
  • PCF re-render infini : Oublie notifyOutputChanged → stack overflow ; call seulement sur vrai change.
  • Patch non délégable : Sur collections locales → sync issues ; priorisez data sources natifs.

Pour aller plus loin

Approfondissez avec les docs officiels PCF, intégrez Power Automate pour workflows post-Patch, ou créez datasets PCF pour grids custom. Découvrez nos formations Learni sur Power Platform pour certification PL-400. Explorez Fluent UI React pour PCF designs enterprise.