最初のコンポーネントを作成する

このチュートリアルでは、ユーザーが列に値を入力する代わりに、視覚的なスライダーを使用して数値を変更できるようにする線形スライダーコード コンポーネントを作成する方法を示します。

注意

エンティティとテーブルの違いがわかりませんか? Microsoft Dataverse で「開発者: 用語を理解する」を参照してください。

線形スライダー コード コンポーネントを構築するには、次の手順が必要です。

前提条件

このチュートリアルでは、次のコンポーネントをインストールする必要があります。

  1. Visual Studio Code (VSCode) ([パスに追加] オプションが選択されていることを確認してください)
  2. node.js (LTS バージョンが推奨されています)
  3. Microsoft Power Platform CLI (Visual Studio Code 拡張機能または MSI インストーラーのいずれかを使用します)
  4. 次のいずれかをインストールして、.NET ビルド ツールを作成します: (少なくとも、ワークロード .NET build tools を選択します。)

注意

Visual Studio 用ビルド ツールの代わりに、.NET 5.x SDK を使用したいと思うかもしれません。 この場合、msbuild を使用する代わりに dotnet build を使用します。

ヒント

ソース管理用 git をインストールすることもお勧めします。

新しいコンポーネント プロジェクトを作成する

新しいプロジェクトを作成するには:

  1. コマンド プロンプト ウィンドウを開きます。 次のコマンドを使用してプロジェクトの新しいフォルダを作成します:

     mkdir LinearInput
    
  2. Visual Studio Code 内の LinearInput フォルダを開きます。 開始する最も簡単な方法は、プロジェクトディレクトリに入ったら、cd LinearInput を使用して、コマンドプロンプトから code . を実行することです。 このコマンドは、 Visual Studio Code にあるコンポーネントプロジェクトを開きます。

  3. ターミナル -> 新しいターミナル を使用して Visual Studio Code 内部に新しいターミナルを開きます。

  4. ターミナル プロンプトで、コマンドを使用して基本パラメータを渡すことで新しいコンポーネントプロジェクトを作成します。

     pac pcf init --namespace SampleNamespace --name LinearInputControl --template field
    
  5. 上記のコマンドは、プロジェクトのビルド ツールを設定する npm install コマンドも実行します。

    Running 'npm install' for you...
    

    注意

    The term 'npm' is not recognized as the name of a cmdlet, function, script file, or operable program. というエラー メッセージが表示された場合、node.js (LTS 版を推奨) とその他すべての前提条件がインストールされているかどうかを確認してください。

  6. npm をインストールした後で、以下のコマンドを使用して、このディレクトリに ManifestDesignTypes.d.ts ファイルを生成する必要があります。"

    npm run refreshTypes
    

マニフェストの実装

コントロール マニフェストは、コード コンポーネントのメタデータを含む XML ファイルです。 また、コード コンポーネントの動作も定義します。 このチュートリアルでは、LinearInputControl サブフォルダーでマニフェスト ファイルが作成されます。 Visual Studio Code で ControlManifest.Input.xml ファイルを開く場合、マニフェストが一部のプロパティに定義済であることがわかります。 詳細: マニフェスト

次のように定義済みマニフェスト ファイルへの変更を実施します:

  1. コントロール ノードは、コード コンポーネントの名前空間、バージョン、および表示名を定義します。 ここでは、ここで示すように、制御 ノードの各プロパティを定義します:

    • 名前空間: コード コンポーネントの名前空間。

    • コンストラクター: コード コンポーネントのコンストラクター。

    • バージョン: コンポーネントのバージョン。 コンポーネントを更新すると、実行時に変更を表示するの最新バージョンに更新する必要があります。

    • 表示名前キー: UIに表示するコード コンポーネントの名前。

    • 表示名キー: UIに表示するコード コンポーネントの説明。

    • control-type: コード コンポーネントの種類。 コード コンポーネントの 標準 タイプのみがサポートされています。

      <?xml version="1.0" encoding="utf-8" ?>
      <manifest>
      <control namespace="SampleNamespace" constructor="LinearInputControl" version="1.1.0" display-name-key="LinearInputControl_Display_Key" description-key="LinearInputControl_Desc_Key" control-type="standard">
      
  2. プロパティ ノードは、列のデータ型の定義など、コード コンポーネントのプロパティを定義します。 プロパティ ノードに、control 要素下で子要素として指定されます。 ここに示されている通り、プロパティ ノードを定義します:

    • 名前: プロパティの名前。

    • 表示名前キー: UIで表示するプロパティの表示名。

    • 表示名キー: UIに表示するプロパティの説明。

    • of-type-group: of-type-group は 3 つ以上のデータ型列が必要な場合に使用されます。 of-type-group 要素をマニフェストの property 要素の兄弟として追加します。 of-type-group はコンポーネント値を指定し、整数、通貨、浮動小数点、または 10 進数値を含めることができます。

    • 使用: 2 つのプロパティ、バインド入力 を持っています。 バインドされたプロパティは、列の値にのみバインドされます。 入力プロパティは、列にバインドされるか、静的な値を許可します。

    • 必須: プロパティが必須かどうかを定義します。

      <property name="controlValue" display-name-key="controlValue_Display_Key" description-key="controlValue_Desc_Key" of-type-group="numbers" usage="bound" required="true" />
      
  3. リソースノードは、コード コンポーネントのビジュアル化を定義します。 これはコード コンポーネントのビジュアル化とスタイル化を構築するすべてのリソースが含まれています。 コード は、リソース要素下で子要素として指定されます。 以下に示されるように、リソース を定義します:

    • コード: すべてのリソース ファイルが設置されるファイル パスを参照します。

      <resources>
         <code path="index.ts" order="1" />
         <css path="css/LinearInputControl.css" order="1" />
      </resources>
      

      マニフェスト ファイル全体は、次のように表示されます。

      <?xml version="1.0" encoding="utf-8" ?>
      <manifest>
        <control namespace="SampleNamespace" constructor="LinearInputControl" version="1.1.0" display-name-key="LinearInputControl_Display_Key" description-key="LinearInputControl_Desc_Key" control-type="standard">
            <type-group name="numbers">
               <type>Whole.None</type>
               <type>Currency</type>
               <type>FP</type>
               <type>Decimal</type>
            </type-group>
            <property name="controlValue" display-name-key="controlValue_Display_Key" description-key="controlValue_Desc_Key" of-type-group="numbers" usage="bound" required="true" />
          <resources>
            <code path="index.ts" order="1" />
            <css path="css/LinearInputControl.css" order="1" />
          </resources>
        </control>
      </manifest>
      
  4. ControlManifest.Input.xml ファイルに加えた変更を保存します。

コンポーネント ロジックの実装

マニフェスト ファイルを実行した後の次の手順は、TypeScript を使用してマニフェスト ファイルをコンポーネントのロジックに実装することです。 コンポーネントのロジックは、index.ts ファイル内で実装する必要があります。 Visual Studio Code で index.ts ファイルを開くと、4 つの重要な関数が事前定義されていることがわかります。 次に、コード コンポーネントのロジックを実装します。

  1. 任意のコードエディタで index.ts ファイルを開きます。
  2. 次のコードで LinearInputControl クラスを更新します。
import { IInputs, IOutputs } from "./generated/ManifestTypes";

export class LinearInputControl implements ComponentFramework.StandardControl<IInputs, IOutputs> {
   private _value: number;
   private _notifyOutputChanged: () => void;
   private labelElement: HTMLLabelElement;
   private inputElement: HTMLInputElement;
   private _container: HTMLDivElement;
   private _context: ComponentFramework.Context<IInputs>;
   private _refreshData: EventListenerOrEventListenerObject;

   public init(context: ComponentFramework.Context<IInputs>, notifyOutputChanged: () => void, state: ComponentFramework.Dictionary, container: HTMLDivElement): void {
      this._context = context;
      this._container = document.createElement("div");
      this._notifyOutputChanged = notifyOutputChanged;
      this._refreshData = this.refreshData.bind(this);

      // creating HTML elements for the input type range and binding it to the function which refreshes the control data
      this.inputElement = document.createElement("input");
      this.inputElement.setAttribute("type", "range");
      this.inputElement.addEventListener("input", this._refreshData);

      //setting the max and min values for the control.
      this.inputElement.setAttribute("min", "1");
      this.inputElement.setAttribute("max", "1000");
      this.inputElement.setAttribute("class", "linearslider");
      this.inputElement.setAttribute("id", "linearrangeinput");

      // creating a HTML label element that shows the value that is set on the linear range control
      this.labelElement = document.createElement("label");
      this.labelElement.setAttribute("class", "LinearRangeLabel");
      this.labelElement.setAttribute("id", "lrclabel");

      // retrieving the latest value from the control and setting it to the HTMl elements.
      this._value = context.parameters.controlValue.raw!;
      this.inputElement.setAttribute("value", context.parameters.controlValue.formatted ? context.parameters.controlValue.formatted : "0");
      this.labelElement.innerHTML = context.parameters.controlValue.formatted ? context.parameters.controlValue.formatted : "0";

      // appending the HTML elements to the control's HTML container element.
      this._container.appendChild(this.inputElement);
      this._container.appendChild(this.labelElement);
      container.appendChild(this._container);
   }

   public refreshData(evt: Event): void {
      this._value = (this.inputElement.value as any) as number;
      this.labelElement.innerHTML = this.inputElement.value;
      this._notifyOutputChanged();
   }

   public updateView(context: ComponentFramework.Context<IInputs>): void {
      // storing the latest context from the control.
      this._value = context.parameters.controlValue.raw!;
      this._context = context;
      this.inputElement.setAttribute("value", context.parameters.controlValue.formatted ? context.parameters.controlValue.formatted : "");
      this.labelElement.innerHTML = context.parameters.controlValue.formatted ? context.parameters.controlValue.formatted : "";
   }

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

   public destroy(): void {
      this.inputElement.removeEventListener("input", this._refreshData);
   }
}
  1. index.ts ファイルへの変更を保存します。

コード コンポーネントにスタイルを追加する

開発者およびアプリ作成者は、CSS を使用してコード コンポーネントを表するためのスタイルを定義できます。 CSS は、スタイル、、色、レイアウトやフォントを含む、コード コンポーネントのプレゼンテーションを開発者が説明できるようにします。 線形入力コンポーネントの init メソッドは、入力の要素を作成し、クラス属性を linearslider に設定します。 linearslider クラスのスタイルは別に CSS ファイルで定義されます。 CSS ファイルのような追加のコンポーネント リソースをコード コンポーネントに含め、さらにカスタマイズをサポートすることができます。

重要

CSS を使用してコード コンポーネントにスタイルを実装する場合は、コンポーネントのコンテナー DIV 要素に適用される自動生成された CSS クラスを使用して、CSS がコントロールにスコープ設定されていることを確認してください。 CSS がグローバルにスコープ設定されている場合、コード コンポーネントが表示されるフォームまたは画面の既存のスタイルが損なわれる可能性があります。 サード パーティの CSS フレームワークを使用している場合は、すでに名前空間が設定されているフレームワークのバージョンを使用するか、手動で、または CSS プリプロセッサを使用して、そのフレームワークを名前空間にラップします。

  1. LinearInputControl フォルダの下に新しい css サブフォルダを作成します。

  2. css サブ フォルダの中に新しい LinearInputControl.css ファイルを作成します。

  3. 以下のスタイル コンテンツを LinearInputControl.css ファイルに追加します:

    .SampleNamespace\.LinearInputControl input[type=range].linearslider {   
       margin: 1px 0;   
       background:transparent;
       -webkit-appearance:none;
       width:100%;padding:0;
       height:24px;
       -webkit-tap-highlight-color:transparent
    }
    .SampleNamespace\.LinearInputControl input[type=range].linearslider:focus {
       outline: none;
    }
    .SampleNamespace\.LinearInputControl input[type=range].linearslider::-webkit-slider-runnable-track {   
       background: #666;
       height:2px;
       cursor:pointer
    }   
    .SampleNamespace\.LinearInputControl input[type=range].linearslider::-webkit-slider-thumb {   
       background: #666;   
       border:0 solid #f00;
       height:24px;
       width:10px;
       border-radius:48px;
       cursor:pointer;
       opacity:1;
       -webkit-appearance:none;
       margin-top:-12px
    }    
    .SampleNamespace\.LinearInputControl input[type=range].linearslider::-moz-range-track {   
       background: #666;   
       height:2px;
       cursor:pointer  
    }   
    .SampleNamespace\.LinearInputControl input[type=range].linearslider::-moz-range-thumb {   
       background: #666;   
       border:0 solid #f00;
       height:24px;
       width:10px;
       border-radius:48px;
       cursor:pointer;
       opacity:1;
       -webkit-appearance:none;
       margin-top:-12px
    }   
    .SampleNamespace\.LinearInputControl input[type=range].linearslider::-ms-track {   
       background: #666;   
       height:2px;
       cursor:pointer  
    }    
    .SampleNamespace\.LinearInputControl input[type=range].linearslider::-ms-thumb {   
       background: #666;   
       border:0 solid #f00;
       height:24px;
       width:10px;
       border-radius:48px;
       cursor:pointer;
       opacity:1;
       -webkit-appearance:none;
    }
    
  4. LinearInputControl.css ファイルを保存します。

  5. ControlManifest.Input.xml ファイルには、リソース要素内に CSS リソース ファイルが含まれていることに注意してください。

    <resources> 
      <code path="index.ts" order="1"/> 
      <css path="css/LinearInputControl.css" order="1"/> 
    </resources> 
    

注意

Power Apps component framework は、ローカライズされた文字列の管理に使用される文字列 (resx) Web リソースを実装する概念を使用し、任意のユーザー インターフェイスに表示されます。 詳細: 文字列 (Resx) Web リソースresx Web リソースを使用してコード コンポーネントをローカライズする方法については、ローカライズ API サンプル を参照してください。

コード コンポーネントを構築する

マニフェスト、コンポーネント ロジック、スタイルの追加が完了したら、次のコマンドを使用してコード コンポーネントをビルドします:

npm run build

ビルドは、LinearInputControl/generated フォルダーの TypeScript 型の宣言ファイルを作成および更新します。 コンポーネントは out/controls/LinearInputControl フォルダにコンパイルされます。 構築アーティファクトには以下が含まれます:

  • bundle.js – バンドルされたコンポーネントのソースコード。
  • ControlManifest.xml – Microsoft Dataverse にアップロードされるコンポーネント マニフェスト ファイル。

コード コンポーネントのデバッグ

コード コンポーネント ロジックの実装が完了したら、以下のコマンドを実行してデバッグ処理を開始します。 詳細: コード コンポーネントのデバッグ

npm start watch

コード コンポーネントのパッケージ化

ソリューション ファイルを作成してインポートするには、次の手順に従います:

  1. LinearComponent フォルダー内の新しい フォルダー ソリューション を作成し、フォルダーに移動します。

  2. 次のコマンドを使用して LinearInputControl フォルダに新しいソリューション プロジェクトを作成します。

      pac solution init --publisher-name Samples --publisher-prefix samples 
    

    注意

    publisher-namepublisher-prefix の値は、既存のソリューション発行者、またはターゲット環境で作成する新しい値と同じである必要があります。

  3. 新しいソリューション プロジェクトを作成したら、その作成したコンポーネントが配置される場所を参照する必要があります。 以下のコマンドを使用して参照を追加できます:

     pac solution add-reference --path ..\
    

    注意

    ここで提供されるパスは、LinearInputControl フォルダー下に作成された現在の ソリューション フォルダーに関連付けられています。 また、絶対パスも提供できます。

  4. ソリューション プロジェクトから zip ファイルを生成するには、cdsproj ソリューション プロジェクトのディレクトリ内で、以下のコマンドを使用します。

    msbuild /t:restore
    

    または、.NET 5 SDK をインストールした場合は

    dotnet build
    
  5. 再度、次のコマンドを実行します:

    msbuild
    

    注意

    Missing required tool: MSBuild.exe/dotnet.exe というエラーを受け取った場合。 パス環境変数に MSBuild.exe/dotnet.exe を追加するか、Developer Command Prompt for Visual Studio Code を使用します。 前提条件 で説明したように、.NET ビルド ツールをインストールする必要があります。

    ヒント

    msbuild コマンドを使用したソリューション ファイルをビルドして、Dataverse にインポートしてソリューション チェッカーを実行している場合は、eval 関数やその機能的に同等なものは使用しないでください というメッセージが表示されます。 コマンド msbuild/property:configuration=Release を使用してソリューション ファイルを再構築し、ソリューションを Dataverse に再インポートして、ソリューション チェッカーを実行します。 詳細: コード コンポーネントのデバッグ

  6. 生成されたソリューションの zip ファイルは、Solution\bin\debug フォルダーにあります。

  7. zipファイルが準備ができたらWeb ポータルを使用して、手動で ソリューションを Dataverse にインポートする か、 Microsoft Power Platform Build Tools を使用して自動的にインポートします。

注意

アンマネージド ソリューションをインポートする場合は、カスタマイズを手動で公開します。

モデル駆動型のアプリのコード コンポーネントの追加

線形入力コンポーネントのようなコード コンポーネントを追加するには、記事 列とテーブルにコンポーネントを追加する に記載されている手順に従ってください。

キャンバス アプリにコード コンポーネントを追加する

コード コンポーネントをキャンバス アプリに追加するには、記事 キャンバス アプリにコード コンポーネントを追加する の手順に従ってください。

ポータルへのコードコンポーネントの追加

コードコンポーネントをポータルに追加するには、ポータルでコードコンポーネントを使用する の記事の手順に従ってください。

関連項目

サンプル コンポーネントをダウンロード
Power Apps component framework の学習
既存の Power Apps component framework のコンポーネントを更新する
Microsoft Power Platform Build Tools
Power Apps Component Framework API の参照
Power Apps Component Framework の概要
コード コンポーネントのデバッグ

注意

ドキュメントの言語設定についてお聞かせください。 簡単な調査を行います。 (この調査は英語です)

この調査には約 7 分かかります。 個人データは収集されません (プライバシー ステートメント)。