
Gallery.Selected はギャラリーで選択したアイテムを取得できる便利なプロパティですが、実は使い続けると厄介なバグの温床になります。フォームとの連携に Gallery.Selected を使っている方は、ぜひ最後まで読んでください。
Gallery.Selected の何が問題なのか
Gallery.Selected とは、ギャラリーコントロールで現在選択されている行のレコードを返すプロパティです。フォームの Item プロパティに Gallery.Selected を設定して詳細・編集フォームと連携するのは、Power Apps を始めて間もない頃に誰もが通る道です。
ところがこの書き方には、新規追加の場面で確実にバグが出ます。新規ボタンを押してフォームを NewForm に切り替えたとき、ギャラリーの選択状態はそのまま残ります。つまり Gallery.Selected には前に選択していたレコードが入ったままです。
このとき何が起きるかというと、新しいレコードを保存してギャラリーが更新された後、フォームが新規レコードではなく前のレコードに戻ってしまいます。保存したはずのデータが画面に反映されず、ユーザーが混乱するというバグです。私自身、これに気づかず何度もテスト環境で首をひねりました。フォームとギャラリーが連動しているように見えて、実は Gallery.Selected がズレたまま動いているというのは、原因が見つかりにくいので本当に厄介です。
新規追加後に前のレコードに戻ってしまう現象
もう少し具体的に追ってみます。タスク管理アプリで、ギャラリーにタスク一覧が表示されていて、右側に EditForm を置いているとします。
- 一覧からタスクAを選択する → フォームにタスクAの内容が表示される
- 新規ボタンを押す → フォームは NewForm になるが、ギャラリーの選択はタスクAのまま
- タスクBを入力して保存する → ギャラリーにタスクBが追加される
- フォームは Gallery.Selected を参照しているため、ギャラリーの選択行(タスクA)に戻る
- ユーザーには保存したタスクBがどこに消えたのかわからない状態になる

これが Gallery.Selected の根本的な問題です。簡単にいえば、ギャラリーの選択という不安定な状態に依存しているため、操作の順番によって結果が変わってしまうのです。
varRecord 変数への置き換え
この問題を解決するのが、コンテキスト変数 varRecord を使ったパターンです。ギャラリーの各行を選択したとき、Gallery.Selected を参照する代わりに、選択したレコードを変数に格納するという考え方です。変数に格納した瞬間の値は不変なので、後でギャラリーの選択が変わっても影響を受けません。
コンテキスト変数とグローバル変数の違いが気になる方は、Power Apps のグローバル変数とコンテキスト変数の使い分けをあわせて確認しておくとスムーズです。ここでは画面ローカルの状態管理なので UpdateContext を使います。
OnSelect に UpdateContext を追加する
ギャラリーの OnSelect プロパティに次の式を追加します。
UpdateContext({varRecord: ThisItem})
ThisItem は OnSelect のタイミングでクリックした行のレコードです。これで varRecord に選択した行のデータが格納されます。その後のフォームやラベルは Gallery.Selected ではなく varRecord を参照するように変更します。

これだけで土台は完成です。後は参照先を Gallery.Selected から varRecord に差し替えていくだけです。
フォームの Item を varRecord に変更する
EditForm の Item プロパティを Gallery.Selected から varRecord に変更します。
varRecord
これだけで、ギャラリーの選択状態に関係なく、varRecord に格納されたレコードがフォームに表示されるようになります。新規ボタンを押すときは varRecord を Blank() にリセットすれば、フォームが空になって新規入力モードとして機能します。新規ボタンの OnSelect はこのようにします。
NewForm(EditForm1);
UpdateContext({varRecord: Blank()})

Gallery.Selected を使っていたときと比べると、フォームの動作が安定します。新規追加後の保存でフォームが前のレコードに戻るという現象が起きなくなります。
TemplateFill も varRecord 連動に切り替える
選択行のハイライト表示を実装している場合、TemplateFill の式も変更が必要です。TemplateFill の基本的な仕組みについては、Power Apps ギャラリーで選択行をハイライトする記事で詳しく解説しています。
Gallery.Selected が参照されているときは、IsSelected という組み込みプロパティを使ってハイライトを切り替えているケースが多いです。しかし varRecord に切り替えた後は IsSelected への依存をゼロにするのが理想です。代わりに次の式を使います。
If(ThisItem.ID = varRecord.ID, ColorFade(Color.Blue, 0.7), RGBA(0,0,0,0))
ThisItem.ID と varRecord.ID が一致する行だけ色を変える、という考え方です。これでギャラリーの選択状態(IsSelected)ではなく、変数に何が入っているかでハイライトが制御されます。新規ボタンを押して varRecord が Blank になれば、どの行もハイライトされない状態になります。これが意図どおりの挙動です。

FontWeight の参照を Title1 に集約する
ギャラリー内のラベルで FontWeight を IsSelected に連動させていた場合、そこも書き換えが必要です。たとえばタイトルラベルの FontWeight を選択中なら Bold にするという式で組んでいると、IsSelected の参照が残ることになります。
解決策は、FontWeight の判定ロジックを Title1(ギャラリー内の先頭ラベル)に集約して、他のラベルからは Title1.FontWeight を参照させるパターンです。
| コントロール | プロパティ | 設定値 |
|---|---|---|
| Title1(先頭ラベル) | FontWeight | If(ThisItem.ID = varRecord.ID, FontWeight.Bold, FontWeight.Normal) |
| Subtitle1・Body1 など | FontWeight | Title1.FontWeight |
このように参照先を一本化しておくと、ロジックを変更するときに Title1 の1箇所だけ直せばよくなります。ギャラリーが10列・20列と増えても修正は1箇所で済む。メンテナンス性が上がるので、複雑になる前に習慣づけておくことをおすすめします。体感では、後から直すよりも最初から設計しておいたほうが圧倒的に楽です。

Gallery 全体で IsSelected の参照をゼロにする
varRecord への切り替えが完了したら、ギャラリー内のすべてのコントロールで IsSelected が参照されていないことを確認します。これが最後の仕上げです。
確認の手順はシンプルです。Power Apps Studio の検索機能(Ctrl + F)で IsSelected と入力して、ヒットする箇所を一つずつ確認します。残っている場合はすべて varRecord.ID との比較式か、Title1 への参照に置き換えます。
IsSelected が残っていると、新規ボタンを押したときに前のレコードのハイライトが残ったり、フォームとギャラリーのハイライトが食い違ったりします。一見小さな問題に見えますが、ユーザーが操作するたびに違和感が積み重なります。アプリの品質に直結するので、リリース前に必ず確認しておきましょう。
varRecord への切り替えが済んだら、次のステップとして新規作成後の保存フロー・プレースホルダーUI・OnSuccess の実装パターンについて、ギャラリーとフォームを変数でつなぐ記事で詳しく解説しています。
まとめ
Gallery.Selected は手軽ですが、新規入力フォームとの組み合わせで必ずズレが発生します。varRecord を使ったパターンに置き換えることで、ギャラリー・フォーム・ハイライトを変数ベースで一貫して制御できるようになります。
最初は手間に感じるかもしれません。でもこのパターンを覚えると、中〜大規模のアプリを作るときに迷わなくなります。Gallery.Selected のズレで何時間も悩むよりも、最初から varRecord で設計するほうが結果的に速いです。地道な一手間ですが、アプリの安定性を大きく高めてくれる変更です。楽しみながら取り組んでみてください。
ギャラリーの使い方を一覧でまとめた記事はこちらからご覧ください。