- 記事一覧 >
- ブログ記事
Power Apps 高さが不定のコンテンツに対応する縦スクロールバー画面
はじめに
Power Apps のキャンバスアプリで、縦スクロールバーを表示したい場面がありました。
理由は、前回記事「Power Apps のギャラリーでエクセル風 編集可能なグリッドテーブルを作成 1/2」のようにギャラリーでテーブル状にデータを表示して、その行数が不定だからです。
それだけだと、"ギャラリーにスクロールバーを表示すればよい。" で終わりなので、初めに要件を整理します。
要件 | |
---|---|
1 | キャンバスアプリは、タブレット横向きのみ想定。 |
2 | スクロールは縦のみとする。 |
3 | スクロールする部分は、画面の一部。(画面全体ではない。) |
4 | スクロール範囲に限界は無いものとする。(最大 4096 ピクセルとかはNG。) |
5 | スクロールバーは、画面内に一つだけとする。 |
6 | ギャラリーのスクロールバーを使ってはいけない。理由は、スクロールバー有りのギャラリーが複数ある場合、複数スクロールしなければいけないから。(上の要件の理由でもある) |
7 | ギャラリーの1行の高さ(TemplateSize)は、固定とする。 |
8 | ギャラリーの他、ラベルの高さも不定(AutoHeight=true )とする。 |
9 | スクロール領域内にコンポーネントを自由に配置できるものとする。 |
今回、これを満たす方法を2つやってみましたので、まとめていきます。
流体グリッドを使う
普通に考えると、コレになると思います。
動作デモ
完成後のスクロールの様子です。
構築手順
Screen1 にギャラリーを使ったテーブルが以下のようにあるものとします。 行数は、20 行です。1行あたりの高さは、40 です。
テーブルの作り方については、「Power Appsのギャラリーでエクセル風 編集可能なグリッドテーブルを作成 1/2」をご確認ください。
一番上の "メンバーID", "名前", "年齢" の表示部分はラベルです。
データ部分は、
TemplateSize=40
のギャラリーです。ギャラリー内にテキスト入力を3つ配置しています。
新しい画面 → テンプレート → スクロール可能 を選択して、新規スクリーン Screen2 を作成します。
すると、スクリーンが追加されて、流体グリッドとその中にカードが一つだけ生成されます。カードは、流体グリッド内で部品を並べる枠です。カードは、複数追加できます。
カード内の部品がカードより大きい場合は、部品を全て表示しようとして、カードが広がります。カードが広がった分、スクロールバーが表示されます。
ラベルとギャラリー(ここでは、Gallery1
とします。)を コピー → カードを選択して、カード内に 貼り付けします。
各プロパティを変更します。
■ ラベル
0
■ Gallery1
40
Y の値は、カード内で移動できずに設定できないかもしれません。その場合は、大きさを手動で調整します。
CountRows(Self.AllItems)*40
■ カード
40 + Gallery1.Height
ここまででこの状態になります。
セクションの追加 をクリックします。
「セクションの追加」とは、カードの追加の意味です。"セクション"と言いつつ、追加される部品は、カードです。
「セクションの追加」と表示されている部分は、実際のアプリには表示されません。
セクションで分ける理由は、普通に並べただけの場合、上に配置されている部品の高さが高くなると、被さってくるからです。(上の部品が下に伸びてきても、下の部品は、よしなにどいてくれません。)
ラベル(ここでは、Label4
とします。)を配置して、テキストを設定します。
各プロパティを変更します。
■ Label4
"今日は天気が良いから、公園でピクニックをしようと思っている。お弁当には、サンドイッチやフルーツ、ジュースを用意している。友達と一緒に、楽しい時間を過ごせることを楽しみにしている。最近、忙しい日々が続いていたから、のんびりとした時間が過ごせることが嬉しい。また、今度はバーベキューもしてみたいなと考えている。"
500
true
セクションの追加 をクリックします。(ここで作成されたカードを、DataCard3
とします。)
垂直ギャラリーを追加して、切り取り → カードを選択して、DataCard3
に貼り付けします。(ここで、追加したギャラリーを Gallery2
とします。)
データソースは、選ばず、CustomGallerySample
のままとします。
各プロパティを変更します。
■ Gallery2
200
CountRows(Self.AllItems)*200
0
■ DataCard3
Gallery2.Height
ここまでで、以下のようになります。
データ量を動的に変更
データ量を動的に変更してみます。
適当な場所にボタンを配置して、OnSelect を以下のようにします。
・テーブルデータの後半 10 行削除。
・Label4
をもっと長文にする。
・DataCard3
の Visible を false
にする。
Visible を
false
にするべきなのは、カードの方です。DataCard3
の中のGallery2
の Visible をfalse
にした場合、空白が残ります。
■ App
Set(Label4Text, "今日は天気が良いから、公園でピクニックをしようと思っている。お弁当には、サンドイッチやフルーツ、ジュースを用意している。友達と一緒に、楽しい時間を過ごせることを楽しみにしている。最近、忙しい日々が続いていたから、のんびりとした時間が過ごせることが嬉しい。また、今度はバーベキューもしてみたいなと考えている。");
Set(DataCard3Visible, true);
この後、OnStart を実行しておきます。
■ Label4
Label4Text
■ DataCard3
DataCard3Visible
■ ボタン
RemoveIf(Members, Value(MemberID) > 10);
Set(Label4Text, "あの人が来ると、いつも私たちはワクワクしてしまう。彼女の笑顔や話し方が、心地よくて癒やされるからだろう。彼女はいつも明るく、ポジティブな言葉をかけてくれる。私たちは彼女の存在がなければ、生活に色を失ってしまうだろう。彼女のような存在は、本当に貴重だと感じる。
今日は天気が良いから、公園でピクニックをしようと思っている。お弁当には、サンドイッチやフルーツ、ジュースを用意している。友達と一緒に、楽しい時間を過ごせることを楽しみにしている。最近、忙しい日々が続いていたから、のんびりとした時間が過ごせることが嬉しい。また、今度はバーベキューもしてみたいなと考えている。
この本はとても面白くて、読み始めたら止まらなくなった。登場人物たちの心情描写が丁寧に描かれていて、感情移入しやすかった。結末も予想外で、読み終わった後もしばらく余韻に浸ってしまった。次はこの作家の他の作品も読んでみたいと思っている。
先日、友人と一緒に美味しいお寿司を食べに行った。新鮮なネタと、職人技が光る握りが最高だった。店内は和風で落ち着いた雰囲気で、話しやすかった。最後にデザートも出してくれて、お腹いっぱい満足した。また、行きたいと思うお店だ。
週末は久しぶりに家族で旅行に行くことになった。目的地は温泉地で、のんびりと温泉に入りながら過ごす予定だ。宿泊するホテルには、温泉と美味しい料理が楽しめるという口コミを聞いて期待が高まっている。家族でのんびりと過ごせる時間を楽しみにしている。");
Set(DataCard3Visible, false);
結果、以下のようになります。
Note
カードを上下入れ替えたいと思っても、入れ替えられません。
...と最初思っていたのですが、上下入れ替え方法がありました!
カードのプロパティの Y を変更して入れ替えられます。
カードの上から、Y=0
, 1
, 2
となっていて、例えば、Y=0
, 2
, 1
とすると、真ん中と一番下が入れ替わります。
垂直コンテナ―を使う
垂直コンテナ―を使うと部品を積み重ねていけます。部品を入れ替える操作が直感的です。
動作デモ
構築手順
新しい画面 → 空の画面 で Screen3
を作って、垂直コンテナ―を配置します。(ここで作成されたカードを、Container1
とします。)
上の方にある青い帯は、Screen2 からコピペして、配置したものです。
垂直コンテナ―を横幅いっぱい、縦スクロールバーありにしておきます。
■ Container1
Screen2.Width
LayoutOverflow.Scroll
Screen2 から テーブル状のラベルとギャラリー(Gallery1
)を コピー → Container1
を選択して、Container1
内に 貼り付けします。(Label1_1
、Label2_1
、Label3_1
、Gallery1_1
とします。)
ここで、2つ問題が発生します。
1.ギャラリーの全行が表示されていない。
2.ラベルが縦に積み重なっている。
1に関しては、ギャラリーを選択して、高さ(伸縮可能) をオフにすると解消します。
高さ(伸縮可能) がオンの場合、現状枠内に収まろうとして、Hight=CountRows(Self.AllItems)*40
が無視されます。
2に関しては、垂直コンテナ―の仕様ため、どうしようもありません。
ラベルを横に並べないといけないのですが、コンテナの中の1部品は、1行になります。
そこで、垂直コンテナ―の中に空のギャラリーを配置して、その中に自由配置したい部品を入れます。(ここで作成されたギャラリーを、Gallery3
とします。)
さらに、データソースを指定しないと、CustomGallerySample
がデータソースになるため、Items に意味のない1レコードだけのデータソースを直接入力します。
垂直コンテナ―の中に追加した部品は、垂直コンテナ―の一番下に追加されます。この時点で見えなくなるため、Alt を押しながらスクロールバーを動かす必要があります。
Gallery3
の高さ(伸縮可能) をオフにして、以下のプロパティを設定します。
■ Gallery3
[{Id: 1, Value:""}]
40
Parent.Width
40
0
false
このギャラリーの中に先ほどのラベルを 切り取り → CTRL + V で配置します。
編集モードにしたギャラリーに対して、CTRL + V が必要です。貼り付け の場合、コンテナーに貼り付けられました。
並べられました!
ただ、データテーブル部分が上にあります。
これの解消は簡単です。
・・・ クリック → 再配列 → 上へ移動 で順番を変えられます。
順番が入れ替わりましたが、ずれています。Gallery1_1
の中のテキスト入力の位置を合わせます。
"メンバーID" のラベルの X が 40
のため、X=40
起点にします。
■ txt_MemberID_1
40
■ txt_Name_1
txt_MemberID_1.X + txt_MemberID_1.Width
■ txt_Age_1
txt_Name_1.X + txt_Name_1.Width
Screen2 から ラベル(Label4
)を コピー → Container1
を選択して、Container1
内に貼り付けします。(Label4_1
とします。)
Alt を押しながらスクロールバーを動かして、一番下を見ると、特に問題無く追加されています。
ちょっとくっつきすぎなので、パティングを調整します。
上:15
、下:15
、左:40
、右:5
とします。
垂直コンテナ―の中の部品の位置関係ですが、左端、中央、右端、横幅いっぱい と選べます。
Screen2 から ギャラリー(Gallery2
)を コピー → Container1
を選択して、Container1
内に貼り付けします。(Gallery2_1
とします。)
Gallery2_1
の高さ(伸縮可能) をオフにして、以下のプロパティを設定します。
■ Gallery2_1
AlignInContainer.Start
ギャラリーが左端に寄っていますが、左だけのパディングがなく、左だけ空けたい場合は、コンテナを入れ子にして、左パディングを設定するか、"メンバーID"、"名前"、"年齢" のラベルの時のように、ギャラリーを入れ子にするしかないと思われます。
最後に、Screen2 で作ったボタンを垂直コンテナ―の外に貼り付けます。OnSelect のコードは残っているため、そのまま使います。
Screen2 のときは、DataCard3
の Visible を変えていましたが、今回は、Gallery2_1
の Visible を変更します。(ややこしいですが、変数名は、DataCard3Visible
のまま維持するものとします。)
■ Gallery2_1
DataCard3Visible
動かしてみます。
ヨシッ!
Note
・・・ クリック → 再配列 → [一番上に移動 | 上へ移動 | 下へ移動 | 一番下に移動]
で、垂直コンテナ―の部品を上下に移動できます。
この移動に関して、キーボードショートカットはなさそうです。
部品と部品の間を空けたい時、透明のラベルなどを挟めば、空けられます。
その他、宣伝、誹謗中傷等、当方が不適切と判断した書き込みは、理由の如何を問わず、投稿者に断りなく削除します。
書き込み内容について、一切の責任を負いません。
このコメント機能は、予告無く廃止する可能性があります。ご了承ください。
コメントの削除をご依頼の場合はTwitterのDM等でご連絡ください。