【PowerApps】リストボックスの選択アイテムをボタンで操作する

## 動画でも解説しました

<iframe width="560" height="400" src="https://www.youtube.com/embed/3SpkdTMdTkA?si=f0owXqm2D0gCdj1h" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>

## リストボックスで選択アイテムを指定するには
先日ギャラリーで選択行をボタンで操作する方法についても書きました。

https://qiita.com/usagikobo2024/items/9e468b782080c7f23bf1

ギャラリーの場合は、Select関数を使用して、```Select(Gallery1,選択したい行番号)```と書くことで選択する行を指定することができるため、比較的簡単に操作することができます。
しかし、リストボックスでは同じ方法は使えません。

## Defaultプロパティでアイテムを指定する
そこで、Defaultプロパティを使用して選択するアイテムを指定します。
Defaultプロパティに文字列で"いろは"と入れることで、リストボックスのアイテム"いろは"を選択することができます。
この場合、複数選択をオフにしていても、リストボックスのアイテムに"いろは"が複数存在した場合は、すべて選択されてしまうことに注意してください。

## ボタンで操作するには
ボタンで選択アイテムを操作するには、リストボックスの複数選択をオフにして、Defaultプロパティには変数を指定しておきます。
ここでは、変数_selectlbとしておきます。
そして、リストボックスに表示したいアイテムを読み込むタイミングで、行番号を付けておきます。
動画では画面を読み込む際に行番号を付けておきました。

## リストボックス用のコレクションを準備

![testlist1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3880604/47277d4c-6110-8314-add5-1049646495ef.png)
こちらが使用したリストです。
画面のOnVisibleプロパティに以下を記載して読み込みます。
```java
Clear(col_list);                                  //リストボックス用のコレクションを準備
With({pre_list:Distinct(test_list1,memo)},        //pre_listにリストのmemoを重複を削除して格納
    ForAll(Sequence(CountRows(pre_list)),         //pre_listの行数分繰り返し処理
        With({_memo:Index(pre_list,Value).Value}, //pre_listのValue列の値を_memoに格納
        Collect(col_list,{memo:_memo,Row:Value})) //コレクションにmemoとRow(行番号)を追加
    )
);
```
test_list1のmemo列をリストボックスのアイテムとして読み込みました。
ForAll関数で、リストの行数分繰り返して、行番号Row列を作成しています。

リストボックスの項目(Itemsプロパティ)は、col_listを設定。Valueにmemoを設定すると、アイテムにmemo列の値が並びます。

ListBox1
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3880604/4a7effb5-4c9b-d6c9-e318-f3468055e87e.png)


## 最初のアイテムを選択するボタンのOnSelectプロパティ
```java
//リセットして無選択状態にする
Reset(ListBox1);

//col_listの最初の行のmemoを_selectlbに格納する
UpdateContext({_selectlb:First(col_list).memo})
```
はじめのReset関数でリストボックスを初期化して、無選択状態にします。
これを入れておかないと、複数選択してしまいます。
First関数でコレクションの最初のレコードのmemo列の値を取得して、_selectlbに格納します。
ボタンを押すと最初のアイテムである"いろは"が選択されます。


## 最後のアイテムを選択するボタンのOnSelectプロパティ
```java
//リセットして無選択状態にする
Reset(ListBox1);

//col_listの最後の行のmemoを_selectlbに格納する
UpdateContext({_selectlb:Last(col_list).memo})
```
First関数をLast関数に置き換えただけですが、これで最後のアイテムを選択することができます。

## 現在の選択アイテムの１つ上に移動するボタンのOnSelectプロパティ
```java
//_nextrowに現在の選択アイテムのRowに1を足して格納
With({_nextrow:First(ListBox1.SelectedItems).Row - 1},
    If(_nextrow > 0,
        //リセットして無選択状態にする
        Reset(ListBox1);
        //_nextrowをcol_listから探して、memoを取得し_selectlbに格納
        UpdateContext({_selectlb:Index(col_list,_nextrow).memo})
    )
)
```
現在の選択アイテムの行番号から-1し、コレクションから該当する行のmemo列の値を取得。
選択する行番号が０より大きい場合のみ、移動を実行します。
これがないと0以下の場合Index関数でエラーになります。
変数_selectlbに格納することで、一つ上のアイテムを選択します。

## 現在の選択アイテムの１つ下に移動するボタンのOnSelectプロパティ
```java
//_nextrowに現在の選択アイテムのRowに1を足して格納
With({_nextrow:First(ListBox1.SelectedItems).Row + 1},
    If(_nextrow <= CountRows(col_list),
        //リセットして無選択状態にする
        Reset(ListBox1);
        //_nextrowをcol_listから探して、memoを取得し_selectlbに格納
        UpdateContext({_selectlb:Index(col_list,_nextrow).memo})
    )
)
```
こちらは１つ下のアイテムに移動します。
変更点は最初の行で＋１していることと
If関数で、コレクションの最大行以下の場合のみ実行するようにしています。

## 残念なお知らせ
これでリストボックスのアイテムをボタンで操作できるようになりますが、
リストボックスのアイテムが多い場合、表示されていない行のアイテムを選択した際に、アイテムを選択はできるのですが、<B>ギャラリーのように自動でスクロールはしてくれません</B>。
スクロールまでできれば完璧だったのですが、恐らく複数選択が可能なコントロールなのでスクロールしないものと思われます。