はじめに
Power Appsのコンポーネントでこんな感じのカレンダービューを作成してみました。
できたわ
— コルネ (@koruneko32767) 2022年7月24日
褒めたたえてくれ#PowerApps pic.twitter.com/e1xuW4M1zr
その過程でスクロールバーも作成してので、今回はPower Appsでのスクロールバーの作成方法について纏めてみます。
カレンダー表示しているところはまた今度!
自作のスクロールバーを作成できるとなにが嬉しいの?
Power Appsでスクロール可能な画面を作成したい場合はこの「スクロール可能」を選択する必要があります。
この画面を追加すると、Canvas1
というコントロールがあります。
このCanvas内にコントロールを追加していくことでスクロール可能な画面を作成していくわけですが、コンポーネント内にはこのコントロールは追加できません
ではどうやってスクロール可能なコンポーネントを作成するか?というと以下2点があるかと思います。
- ギャラリーを追加し、ギャラリー内にコントロールを追加する
- スクロールバーを自作する
ギャラリーを使う方法が一番簡単な方法ではありますが、これだと特定のコントロールの組み合わせのループになってしまいます。
自由に配置したコントロールをスクロールによって表示させたい場合はスクロールバーを自作する必要があるというわけです。
後は一部の人に対する需要ですが、SVGで描画した際にスクロールバー自作できると色々捗りますね。
スクロールバーを作成する
スクロールバーの構成
スクロールバーは「スライダー」とアイコンの「四角形」の2つで構成されています。
完成イメージは冒頭のツイート内の動画をご確認ください。
スライダーだけだとスクロールバーっぽくないので、四角形を上に被せている感じです。
スライダーの設定
スクロールバーの肝となる部分です。
縦方向のスクロールバーを作成したいのでレイアウトは"縦"に設定しています。
Layout
Layout.Vertical
スクロールバーの位置やサイズは自由に設定してください。
今回は
X: Parent.Width - Self.Width
Y: 0
Width: 20
Height: Parent.Height
としています。
ご参考までに。
スライダーの数値によってスクロールが今どこまで行われているか判断させたいので
Min
0
Max
Self.Height
にそれぞれ設定します。
あとはスライダーの罫線やレール、ハンドルの色を透明に設定してあげます。
非表示にしたらスライダー触れないので透明にしてくださいね。
デフォルト時の色だけでなく、ホバー時や選択時の色などの設定があるので忘れずに透明にしましょう。
透明にするには
RGBA(0, 0, 0, 0)
のようにアルファ値(第4引数)を0に設定してください。
最後に値の表示(ShowValue
)をfalse
に設定して値が表示されないようにします。
これでスライダーの設定は完了です。
簡単ですね。
実はスクロールバーを作るのはたいして難しくなくって、どちらかというとこの値を使って座標などの値を変化させる方が面倒だったりします。
四角形の設定
これがスクロールバーのバーの箇所になります。
実際はスライダーを変更させるわけですので、四角形はスライダーの下にくるように配置してください。
バーのサイズは、幅はスライダーに合わせたいので、
Width
ScrollBarSlider.Width
としています。
高さは適当に
Height
Parent.Height / 6.4
としています。
もっとページの高さによってちゃんと計算させた方がいいかもしれませんが、まぁこれでもそれっぽくなるので。
一点注意するとすれば、固定値はやめましょう。
どこかでも解説したような気がしますが、コンポーネントを作成する際はなるべく他のコントロールの値などを相対的に参照するようにして固定値(マジックナンバー)を設定しないほうがよいです。
理由は、コンポーネントはどのようなサイズでそのアプリに組み込まれることになるかわからないので、ある程度アプリ側でコンポーネントのサイズを変更されてもレイアウトが崩れないようにするためです。
Y座標の設定ですが、これがちょっと厄介です。
スライダーを縦に設定すると最上部が最大値で、最下部が最小値になります。
つまり、スクロールバーを下に持っていけばもっていくほど値が小さくなる。というわけですね。
なのでY座標はこれを考慮して設定する必要があります。
これを考慮した式を設定すると
Parent.Height - ScrollBarSlider.Value
となります。
ただし、これではスクロールバーのハンドルの大きさと、バーの高さに差異がある影響で下にスクロールするほど、スライダーの値と四角形の座標のずれが大きくなってしまいます。
このずれを補正するために
ScrollBarSlider.Max * (ScrollBarSlider.Height - Self.Height)
上記のような式で割ってあげます。
纏めると以下のような式になります。
Y
(Parent.Height - ScrollBarSlider.Value) / ScrollBarSlider.Max * (Parent.Height - Self.Height)
これでいい感じに補正が効いてくれるはずです。
以上でスクロールバーの自作は完成です!
あとはこの値を用いてスクロールさせる方法を説明したいと思います。
自作したスクロールバーのスクロール値をコントロールに適用させる
スクロールバーをスクロールさせたらコントロールたちをそれによって移動させたいので、各コントロールのY座標に式を追加させます。
スクロール領域の言葉を以下のように定義しています。
スクロールによってコントロールが動くように見せたければ、下にスクロールさせればコントロールを上に動かして、スクロールを上に動かせばコントロールを下に動かす。というような処理をすればいいですね。
次に考慮しなければいけないのは例えばスクロールバーの値が1動いたら、画面上ではどれだけコントロールを動かすか?というスクロールによるコントロール移動の倍率です。
これは
- スクロール可能な領域の最大高さ
- スクロール可能な領域の実際の高さ
- スクロールバーの値
- スクロールバーの最大値
の4つの要素を使えば算出できます。
これらの要素を考慮して式を作成すると以下のようになります。
[配置したい座標] - ([スクロール可能な領域の最大高さ] - [スクロール可能な領域の実際の高さ]) * ([スクロール可能な領域の実際の高さ] - ScrollBarSlider.Value) / ScrollBarSlider.Max
スクロールバーのバーの座標補正にスクロール領域の倍率を掛けているだけですね。
(Parent.Height - Self.Height)
による反転は不要なので式内に追加していないです。
ちなみにSVGでスクロールバーの値を適用するときは
viewBox='0 "& ([スクロール可能な領域の最大高さ] - Self.Height) * (Self.Height - ScrollBarSlider.Value) / ScrollBarSlider.Max &" "& Self.Width & " " & Self.Height & "'
みたいにすればいいですね。
おまけにもう一つ。
GalleryのTemplateSize = 0
にしたギャラリーにスクロールバーを適用するならこんな感じです。
ThisItem.y - ([スクロール可能な領域の最大高さ] - [スクロール可能な領域の実際の高さ]) * ([スクロール可能な領域の実際の高さ] - ScrollBarSlider.Value) / ScrollBarSlider.Max - (ThisItem.index - 1)
最後の箇所の
- (ThisItem.index - 1)
この部分はTemplateSize = 0
にしたときのずれの補正ですね。
TemplateSize = 0
に設定しても実際にはTemplateSize = 1
になってしまうので微妙にずれが発生しちゃうのでその補正です。
おわりに
以上、Power Appsでスクロールバーを自作する方法でした。
理解しちゃえば(数学さえ理解すれば)そこまで難しい処理じゃないかと思います。
コンポーネントは市民開発者すべてが理解し管理できるようになるのではなく、一部の開発者が開発・運用・管理をして展開できればよいと私は考えているので、これで実運用を行うのも選択肢としてはありかと思います。
このやり方をマスターするとアプリ開発の幅が広がると思いますので、皆さまも是非お試しくださいー
ところどころ説明端折っちゃった箇所もありますので、質問などあればお気軽にコメントなどでお願いします。
次はこれを使って作成したカスタムカレンダーコントロールの解説を行いたいですね。