
ギャラリーの各行をクリックすると詳細が展開され、もう一度クリックすると折りたたまれるUI、いわゆるアコーディオンを Power Apps で実装する方法は3パターンあります。それぞれの仕組みと使い分けを解説します。
この記事はフレキシブル高さギャラリーの基礎知識を前提にしています。AutoHeight の仕組みや Flexible Height の追加方法が気になる方は、フレキシブル高さギャラリー入門の記事を先に読んでおくとスムーズです。
なぜギャラリー内で変数が使えないのか
ギャラリーで展開・折りたたみを実装しようとすると、最初にぶつかる壁があります。ギャラリーの各行は同じテンプレートを使い回しているため、行固有の状態を変数で持てないという制約です。
たとえば UpdateContext({varExpand: true}) を行ごとに持ちたくても、コンテキスト変数は画面単位の変数なのですべての行に影響します。1行目を展開しようとすると全行が展開されてしまうのです。グローバル変数も同じ理由で行ごとの状態管理には使えません。変数の種類と使い分けについてはグローバル変数とコンテキスト変数の違いの記事でまとめています。
この制約を回避する方法が3つあります。順番に見ていきましょう。
パターン①:HTMLテキストコントロールで折りたたみを表現する
最もシンプルなパターンは、HTMLテキストコントロールと AutoHeight を組み合わせて、クリックで展開・折りたたみを切り替えるものです。ただし行ごとの変数は使えないため、この方法では1行だけ展開してあとは閉じるというトグル管理はできません。
代わりに Toggle コントロールを使います。Toggle の Value は行ごとに独立した状態を持てます(内部的に行のテンプレートとして扱われるため)。ただしこれは Power Apps の仕様上の動きであり、必ずしも全バージョンで安定して動くとは限らない点は割り切りが必要です。
// 詳細エリアの Visible プロパティ
Toggle1.Value
テンプレート内に Toggle を置き、詳細テキストを表示するラベルやコンテナの Visible を Toggle1.Value にします。Toggle がオンになった行だけ詳細エリアが表示され、フレキシブルギャラリーによって行の高さが自動で広がります。

パターン②:ネストギャラリーの高さを動的に計算する
詳細エリアに別のテーブルデータ(たとえばタスクに紐づくコメント一覧)を表示したい場合、ネストギャラリーを使います。
ネストギャラリーは親ギャラリーのテンプレート内に子ギャラリーを配置する構成です。子ギャラリーの高さを行数に応じて動的に計算することで、展開・折りたたみを実現します。
// 子ギャラリーの Height プロパティ
CountRows(GalleryComments.AllItems) * GalleryComments.TemplateHeight
CountRows(GalleryComments.AllItems) は子ギャラリーに表示されているレコード数を返します。TemplateHeight は子ギャラリー1行分の高さです。この積が子ギャラリー全体の高さになります。
折りたたみは子ギャラリーの Visible を Toggle1.Value でオン・オフするだけです。Visible が false のとき親ギャラリーのテンプレートは折りたたまれ、true のとき子ギャラリーの高さ分だけ行が展開されます。

パターン③:コレクションに ShowDetails 列を持たせる
最も柔軟で安定したパターンは、コレクションに ShowDetails(boolean型)列を追加して、Patch で行ごとに切り替える方法です。変数ではなくコレクション自体に状態を持たせることで、行ごとの独立した展開・折りたたみが実現できます。
コレクションの準備
データを読み込む際に ShowDetails 列を追加します。
ClearCollect(colTasks,
AddColumns(Tasks, "ShowDetails", false)
)
AddColumns 関数でデータソースのテーブルに ShowDetails 列を追加しながらコレクションに格納します。初期値はすべて false(折りたたみ状態)です。
展開・折りたたみの切り替え
ギャラリーの各行にある展開ボタンの OnSelect で、該当行の ShowDetails だけを反転させます。
Patch(colTasks, ThisItem, {ShowDetails: !ThisItem.ShowDetails})
!ThisItem.ShowDetails は現在の値の反転です。true なら false に、false なら true にします。Patch でコレクションのその行だけを更新するため、他の行の ShowDetails には一切影響しません。これが変数との決定的な違いです。
詳細エリアの Visible は ThisItem.ShowDetails にするだけです。

Expand All・Collapse All の実装
全件展開・全件折りたたみのボタンも簡単に作れます。UpdateIf でコレクション全行の ShowDetails を一括更新します。
// 全件展開ボタン
UpdateIf(colTasks, true, {ShowDetails: true})
// 全件折りたたみボタン
UpdateIf(colTasks, true, {ShowDetails: false})
UpdateIf の第2引数に true を渡すことですべての行が条件に一致するため、全件更新になります。コレクション操作なのでデータソースへの書き込みはなく、画面のローカル状態だけが変わります。これが変数ではなくコレクションの Patch を使う理由です。変数をトグルすると全行に影響してしまい、行ごとの独立制御ができません。

3パターンの比較
| パターン | 仕組み | 向いている用途 | 難易度 |
|---|---|---|---|
| ① Toggle + Visible | Toggle.Value で詳細エリアを表示切替 | シンプルな展開・折りたたみ | 低 |
| ② ネストギャラリー | 子ギャラリーの高さを動的計算 | 詳細に別テーブルデータを表示 | 中 |
| ③ コレクション Patch | ShowDetails 列をコレクションで管理 | 行ごとの安定した状態管理・全件操作 | 中 |
シンプルに始めたいならパターン①、詳細に別データを表示したいならパターン②、Expand All などの全件操作が必要ならパターン③を選ぶのがおすすめです。コレクション操作の基礎についてはコレクション活用入門の記事で改めて確認しておくと、パターン③の実装がよりスムーズになります。
まとめ
ギャラリー内の変数は全行共通になってしまうという制約さえ理解すれば、対処方法は明快です。Toggle・ネストギャラリー・コレクションの Patch、どれも一度作れば次から迷わず使えます。
アコーディオンUIは使いやすいアプリの定番パターンのひとつです。画面のスペースを有効活用しながら情報を整理できるので、社内アプリでも喜ばれることが多いです。ぜひ試してみてください。
ギャラリーの使い方を一覧でまとめた記事はこちらからご覧ください。