作成中のアプリで必要だったので覚え書き。
ギャラリーコントロールを使ってコレクションのアイテムを任意の順番で並べ替える方法です。
スマホアプリのようにアニメーションがないので少々違和感がありますが。
ポイント
- コレクションにはIndex列を用意。
- ギャラリーコントロールのItemsではIndexでソート。
- 並べ替えボタン、PatchやUpdateIfでIndexを入れ替える。
- ギャラリーのAllItemsを参照して並べ替え状態で新しいコレクションに格納。
- 並べ替えたアイテムの色付け解除はタイマーで。
解説
①コレクションを準備してギャラリーコントロールのデータソースに指定
- コレクションのアイテムには1~nの連番を振る必要があります。
- 2つ目のClearCollectは移動したアイテムに色を付けたい場合に使用するもので、SelectedRow列を追加しています。
- 無くても問題ありません。
- ギャラリーコントロールのItemsには
SortByColumns(DataTable,"Index",Ascending)
を設定
ClearCollect(
DataTableBase,
{Index:1,ItemName:"Albedo"},
{Index:2,ItemName:"Diluc"},
{Index:3,ItemName:"Fischl"},
{Index:4,ItemName:"Barbara"},
{Index:5,ItemName:"Xiao"},
{Index:6,ItemName:"Bennett"},
{Index:7,ItemName:"Jean"},
{Index:8,ItemName:"Mona"}
);
ClearCollect(
DataTable,
AddColumns(
DataTableBase,
"SelectedRow",
false
)
);
②ギャラリーコントロールを以下のようなレイアウトに設定
③↑アイコンの設定
- OnSelectを以下のように設定
- 3行目:クリックした行のIndexを一旦0に設定。SelectedRowをtrueにして移動した行の色が変わるように。
- 4行目:ひとつ上の行のIndexを+1(クリック行のインデックスに置き換え)
- 5行目:クリックした行のIndexを-1
- 7行目:色を元に戻すタイマーを起動
With(
{ThisIndex:ThisItem.Index},
Patch(DataTable,ThisItem,{Index:0,SelectedRow:true});
UpdateIf(DataTable,Index = ThisIndex - 1,{Index:ThisIndex});
UpdateIf(DataTable,Index = 0 ,{Index:ThisIndex-1});
);
UpdateContext({TimerStart:true});
- Visibleを以下のように設定。 一番上の行は↑アイコンを非表示に。
If(ThisItem.Index = 1,false,true)
④↓アイコンの設定
・OnSelectは省略、↑アイコンの-1を+1に変更するだけです。
・Visibleは以下のように設定。 一番下の行は↓アイコンを非表示に。
If(ThisItem.Index = CountRows(DataTable),false,true)
⑤ゴミ箱アイコンの設定
- OnSelectを以下のように設定
- アイテムを削除した後、その行より後の行のIndexを-1して上に詰めます。
With(
{ThisIndex:ThisItem.Index},
Remove(DataTable,ThisItem);
UpdateIf(DataTable,Index > ThisIndex,{Index:Index-1})
)
⑥移動した行を色付けする設定(必要な場合)
・ギャラリーコントロールのラベルのFillに以下を設定。
・SelectedRowがtrueのときのみ色が変わるように設定。
If(ThisItem.SelectedRow=true,RGBA(255, 191, 0, 1),RGBA(186, 202, 226, 1))
・タイマーコントロールを用意し、Durationは500、StartはTimerStart変数を設定。
・OnTimerEndで以下を設定、時間経過後にSelectedRowをfalseに戻して色を戻す。
UpdateIf(DataTable,SelectedRow = true,{SelectedRow:false});
UpdateContext({TimerStart:false});
⑦確定ボタン
・OnSelectに以下を設定
・ギャラリーコントロールのアイテムを参照して新しいコレクションにコピー。
・自分が作成中のアプリではJSONとして返却したかったのでJSONに変換するコードも入っています。
Clear(JsonTable);
ForAll(Gallery1.AllItems,
Collect(JsonTable,{Index:Index,ItemName:ItemName})
);
UpdateContext({JsonString:JSON(JsonTable,JSONFormat.Compact)});
あとがき
- 並べ替え部分はアニメーションにできずフィードバックがないので少し違和感。
どういった視覚効果がいいのか模索中。標準コントロールでできるようになればありがたい。
今回はコレクションの並べ替えです。データソースを並べ替える場合は試していません。
おそらく、UpdateIfは委任できないとされているため、PatchとFilterを組み合わせて更新することになると思います。
ギャラリーコントロールで少数に絞る→コレクションに変換→並べ替え→Patch関数でデータソースをアップデートとか?