1. 記事一覧 >
  2. ブログ記事
Power Apps
category logo

Power Apps 高さが不定のコンテンツに対応する縦スクロールバー画面

(更新) (公開)

はじめに

Power Apps のキャンバスアプリで、縦スクロールバーを表示したい場面がありました。
理由は、前回記事「Power Apps のギャラリーでエクセル風 編集可能なグリッドテーブルを作成 1/2」のようにギャラリーでテーブル状にデータを表示して、その行数が不定だからです。
それだけだと、"ギャラリーにスクロールバーを表示すればよい。" で終わりなので、初めに要件を整理します。


Power Apps のキャンバスアプリ 縦スクロールバー 表示 動画


要件
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 を作成します。

新規スクリーン Screen2 を作成


すると、スクリーンが追加されて、流体グリッドとその中にカードが一つだけ生成されます。カードは、流体グリッド内で部品を並べる枠です。カードは、複数追加できます。

流体グリッドとカード


カード内の部品がカードより大きい場合は、部品を全て表示しようとして、カードが広がります。カードが広がった分、スクロールバーが表示されます。

カードが広がった分、スクロールバー表示

ラベルとギャラリー(ここでは、Gallery1 とします。)を コピー → カードを選択して、カード内に 貼り付けします。

ラベルとギャラリーを切り取り


ラベルとギャラリーをカード内に貼り付け


各プロパティを変更します。


ラベル

Y
0

Gallery1

Y
40

Y の値は、カード内で移動できずに設定できないかもしれません。その場合は、大きさを手動で調整します。

カード内大きさを手動で調整

Height
CountRows(Self.AllItems)*40

カード

Height
40 + Gallery1.Height

ここまででこの状態になります。

テーブル設置までのスクロール動作内容 動画


セクションの追加 をクリックします。

セクションの追加をクリック


セクション追加後

「セクションの追加」とは、カードの追加の意味です。"セクション"と言いつつ、追加される部品は、カードです。

「セクションの追加」と表示されている部分は、実際のアプリには表示されません。

セクションで分ける理由は、普通に並べただけの場合、上に配置されている部品の高さが高くなると、被さってくるからです。(上の部品が下に伸びてきても、下の部品は、よしなにどいてくれません。)


ラベル(ここでは、Label4 とします。)を配置して、テキストを設定します。

各プロパティを変更します。


Label4

Text
"今日は天気が良いから、公園でピクニックをしようと思っている。お弁当には、サンドイッチやフルーツ、ジュースを用意している。友達と一緒に、楽しい時間を過ごせることを楽しみにしている。最近、忙しい日々が続いていたから、のんびりとした時間が過ごせることが嬉しい。また、今度はバーベキューもしてみたいなと考えている。"

Width
500

AutoHeight
true

ラベルのプロパティ変更後


セクションの追加 をクリックします。(ここで作成されたカードを、DataCard3 とします。)
垂直ギャラリーを追加して、切り取り → カードを選択して、DataCard3 に貼り付けします。(ここで、追加したギャラリーを Gallery2 とします。)

垂直ギャラリーをDataCard3に貼り付け


データソースは、選ばず、CustomGallerySample のままとします。
各プロパティを変更します。


Gallery2

TemplateSize
200
Height
CountRows(Self.AllItems)*200
Y
0

DataCard3

Height
Gallery2.Height

ここまでで、以下のようになります。

配置が終わった後のスクロール動作内容 動画


データ量を動的に変更

データ量を動的に変更してみます。


適当な場所にボタンを配置して、OnSelect を以下のようにします。
・テーブルデータの後半 10 行削除。
Label4 をもっと長文にする。
DataCard3 の Visible を false にする。

Visible を false にするべきなのは、カードの方です。DataCard3 の中の Gallery2 の Visible を false にした場合、空白が残ります。


App

OnStart
Set(Label4Text, "今日は天気が良いから、公園でピクニックをしようと思っている。お弁当には、サンドイッチやフルーツ、ジュースを用意している。友達と一緒に、楽しい時間を過ごせることを楽しみにしている。最近、忙しい日々が続いていたから、のんびりとした時間が過ごせることが嬉しい。また、今度はバーベキューもしてみたいなと考えている。");
Set(DataCard3Visible, true);

AppのOnStart設定


この後、OnStart を実行しておきます。

AppのOnStart実行


Label4

Text
Label4Text

DataCard3

Visible
DataCard3Visible

ボタン

OnSelect
RemoveIf(Members, Value(MemberID) > 10);
Set(Label4Text, "あの人が来ると、いつも私たちはワクワクしてしまう。彼女の笑顔や話し方が、心地よくて癒やされるからだろう。彼女はいつも明るく、ポジティブな言葉をかけてくれる。私たちは彼女の存在がなければ、生活に色を失ってしまうだろう。彼女のような存在は、本当に貴重だと感じる。
今日は天気が良いから、公園でピクニックをしようと思っている。お弁当には、サンドイッチやフルーツ、ジュースを用意している。友達と一緒に、楽しい時間を過ごせることを楽しみにしている。最近、忙しい日々が続いていたから、のんびりとした時間が過ごせることが嬉しい。また、今度はバーベキューもしてみたいなと考えている。
この本はとても面白くて、読み始めたら止まらなくなった。登場人物たちの心情描写が丁寧に描かれていて、感情移入しやすかった。結末も予想外で、読み終わった後もしばらく余韻に浸ってしまった。次はこの作家の他の作品も読んでみたいと思っている。
先日、友人と一緒に美味しいお寿司を食べに行った。新鮮なネタと、職人技が光る握りが最高だった。店内は和風で落ち着いた雰囲気で、話しやすかった。最後にデザートも出してくれて、お腹いっぱい満足した。また、行きたいと思うお店だ。
週末は久しぶりに家族で旅行に行くことになった。目的地は温泉地で、のんびりと温泉に入りながら過ごす予定だ。宿泊するホテルには、温泉と美味しい料理が楽しめるという口コミを聞いて期待が高まっている。家族でのんびりと過ごせる時間を楽しみにしている。");
Set(DataCard3Visible, false);

結果、以下のようになります。

流体グリッド 完成後のスクロールの様子 動画


Note

カードを上下入れ替えたいと思っても、入れ替えられません。
...と最初思っていたのですが、上下入れ替え方法がありました!

カードのプロパティの Y を変更して入れ替えられます。

カードの上から、Y=0, 1, 2 となっていて、例えば、Y=0, 2, 1 とすると、真ん中と一番下が入れ替わります。

カードのYパラメータ


垂直コンテナ―を使う

垂直コンテナ―を使うと部品を積み重ねていけます。部品を入れ替える操作が直感的です。


動作デモ

垂直コンテナ―を使う場合のスクロール動作内容 動画


構築手順

新しい画面 → 空の画面Screen3 を作って、垂直コンテナ―を配置します。(ここで作成されたカードを、Container1 とします。)

上の方にある青い帯は、Screen2 からコピペして、配置したものです。

垂直コンテナ―を配置


垂直コンテナ―を横幅いっぱい、縦スクロールバーありにしておきます。


Container1

Width
Screen2.Width
LayoutOverflowY
LayoutOverflow.Scroll

Screen2 から テーブル状のラベルとギャラリー(Gallery1)を コピーContainer1 を選択して、Container1 内に 貼り付けします。(Label1_1Label2_1Label3_1Gallery1_1 とします。)

Screen2 から テーブル状のラベルとギャラリーをコピー


テーブル状のラベルとギャラリーを貼り付け


ここで、2つ問題が発生します。


1.ギャラリーの全行が表示されていない。
2.ラベルが縦に積み重なっている。

2つ問題が発生


1に関しては、ギャラリーを選択して、高さ(伸縮可能) をオフにすると解消します。
高さ(伸縮可能) がオンの場合、現状枠内に収まろうとして、Hight=CountRows(Self.AllItems)*40 が無視されます。

高さ(伸縮可能) をオフにすると解消


2に関しては、垂直コンテナ―の仕様ため、どうしようもありません。
ラベルを横に並べないといけないのですが、コンテナの中の1部品は、1行になります。


そこで、垂直コンテナ―の中に空のギャラリーを配置して、その中に自由配置したい部品を入れます。(ここで作成されたギャラリーを、Gallery3 とします。)
さらに、データソースを指定しないと、CustomGallerySample がデータソースになるため、Items に意味のない1レコードだけのデータソースを直接入力します。

垂直コンテナ―の中に追加した部品は、垂直コンテナ―の一番下に追加されます。この時点で見えなくなるため、Alt を押しながらスクロールバーを動かす必要があります。


Gallery3 の高さ(伸縮可能) をオフにして、以下のプロパティを設定します。


Gallery3

Items
[{Id: 1, Value:""}]
Height
40
Width
Parent.Width
TemplateSize
40
TemplatePadding
0
ShowScrollbar
false

このギャラリーの中に先ほどのラベルを 切り取りCTRL + V で配置します。

編集モードにしたギャラリーに対して、CTRL + V が必要です。貼り付け の場合、コンテナーに貼り付けられました。

空のギャラリーを配置して、その中に自由配置


並べられました!


ただ、データテーブル部分が上にあります。


これの解消は簡単です。
・・・ クリック → 再配列上へ移動 で順番を変えられます。

再配列 上へ移動


上へ移動後


順番が入れ替わりましたが、ずれています。
Gallery1_1 の中のテキスト入力の位置を合わせます。
"メンバーID" のラベルの X が 40 のため、X=40 起点にします。


txt_MemberID_1

X
40

txt_Name_1

X
txt_MemberID_1.X + txt_MemberID_1.Width

txt_Age_1

X
txt_Name_1.X + txt_Name_1.Width

ラベルのずれ解消


Screen2 から ラベル(Label4)を コピーContainer1 を選択して、Container1 内に貼り付けします。(Label4_1 とします。)


Alt を押しながらスクロールバーを動かして、一番下を見ると、特に問題無く追加されています。

Alt を押しながらスクロールバーを動かして、一番下


ちょっとくっつきすぎなので、パティングを調整します。
上:15、下:15、左:40、右:5 とします。

垂直コンテナ―の中の部品の位置関係ですが、左端、中央、右端、横幅いっぱい と選べます。

パティングを調整


Screen2 から ギャラリー(Gallery2)を コピーContainer1 を選択して、Container1 内に貼り付けします。(Gallery2_1 とします。)


Gallery2_1 の高さ(伸縮可能) をオフにして、以下のプロパティを設定します。


Gallery2_1

AlignInContainer
AlignInContainer.Start

Gallery2_1 左寄せ

ギャラリーが左端に寄っていますが、左だけのパディングがなく、左だけ空けたい場合は、コンテナを入れ子にして、左パディングを設定するか、"メンバーID"、"名前"、"年齢" のラベルの時のように、ギャラリーを入れ子にするしかないと思われます。


最後に、Screen2 で作ったボタンを垂直コンテナ―の外に貼り付けます。OnSelect のコードは残っているため、そのまま使います。
Screen2 のときは、DataCard3 の Visible を変えていましたが、今回は、Gallery2_1 の Visible を変更します。(ややこしいですが、変数名は、DataCard3Visible のまま維持するものとします。)


Gallery2_1

Visible
DataCard3Visible

動かしてみます。


垂直コンテナ―を使う場合のスクロール動作内容 動画


ヨシッ!


Note

・・・ クリック → 再配列[一番上に移動 | 上へ移動 | 下へ移動 | 一番下に移動]
で、垂直コンテナ―の部品を上下に移動できます。
この移動に関して、キーボードショートカットはなさそうです。

垂直コンテナ―の部品を上下に移動


部品と部品の間を空けたい時、透明のラベルなどを挟めば、空けられます。

loading...