今年の目標
今年、技術系の記事を書きまくって、Microsoft MVP受賞を狙いたいと思います。
がんばります。
今日から週一くらいの頻度で、主に.NET MAUI の記事を書いていきたいと思います。
たまに気分転換に、WPFの記事も書くかもしれません。私はWPFで育ったので。
本題
さて、MAUIには Xamarin.Forms から受け継がれたコントロールが多いようですね。
今回はその一つである、SwipeView を見ていきたいと思います。
SwipeViewは例えば CollectionViewなどの複数のエントリの一つを左右にスワイプすると出てくるボタンのようなものです。
よく、背景が赤の「削除/Delete」のようなボタンが設けられていることが多い気がします。
もちろん、SwipeView単独でも動作しそうなものですが、今回のサンプルではCollectionViewと組み合わせてみたいと思います。
まずこちらの動画をご覧ください。
ではソースコードをどうぞ。
詳しく説明
今回はCollectionViewのItemTemplateの中で、SwipeViewを扱うようにしています。
CollectionViewのItemsSourceに与えられたコレクションは ReactiveCollection
ItemTemplate内のBindingContextにはstring型が入っているため、SwipeItemのCommandには
Command="{Binding BindingContext.LeftSwipeItemCommand, Source={x:Reference page}}"
みたいな書き方をしています。Sourceは x:Name="page"と名付けられた、ContentPageインスタンスに結びつきます。
つまり、ContentPageインスタンスのBindingContextにはSwipeViewSamplePageViewModelインスタンスが入っており、そのLeftSwipeItemCommandをバインディングしているというわけです。
この書き方はWPFに比べて、ややわかりやすく書きやすくなったと言えるでしょう。x:Reference大好き❤
ちなみにSwipeItemのCommandParameterは "{Binding}"となってます。これはSwipeItemのBindingContextをそのまま充てるという意味ですが、SwipeItemのBindingContextはさかのぼると、DataTemplateのx:DataTypeで指定されている型(ここではstring型)で、DataTemplateのデータはCollectionViewのItemsSourceに当てられているコレクションの要素になるので、つまりstringインスタンスが親から継承されてきて、CommandParameterはその値をそのままつかっているという意味になります。
public ReactiveCommandSlim<string> LeftSwipeItemCommand { get; } = new(); public ReactiveCommandSlim<string> RightSwipeItemCommand { get; } = new(); LeftSwipeItemCommand.Subscribe(async str => { await Shell.Current.CurrentPage.DisplayAlert("LeftSwipeItem", "LeftSwipeItem がタップされました。", "OK"); }).AddTo(_disposables); RightSwipeItemCommand.Subscribe(async str => { await Shell.Current.CurrentPage.DisplayAlert("RightSwipeItem", "RightSwipeItem がタップされました。", "OK"); }).AddTo(_disposables);
あとは、ViewModel側で煮るなり焼くなり好きにしてくれっていうことですね。
今回はDisplayAlertを呼び出しています。
懸念点
上の動画を見てもらえるとわかると思うのですが、
このSwipeViewはアニメーションが多少ぎこちないです。
もしかしたら、このアニメーションが許容できなくて企業で開発している場合は、採用を見送ることもあるかと思います。
よりなめらかなSwipeViewを求めて、カスタムコントロールを作るのもありかもしれません。