さて一つ前の記事で、PrismのINavigationAwareを代替するのに、PageクラスのAppearingイベントとDisappearingイベントが利用できる。
というお話をしました。
今回はそれを簡便に実現するための方法を紹介したいと思います。
以前、イベントに反応してコマンドを実行するEventToCommandBehaviorを紹介しました。
www.nuits.jp
これをそのまま利用してもよいのですが、都度ViewModel側にICommandを定義する必要があり煩雑なため、改めて特化したBehaviorを作成してみたいと思います。
それでは早速行ってみましょう。
使い方のイメージ
対応箇所は、ViewとViewModelの2箇所です。
View
画面遷移イベントをハンドルしたいPageに対して、NotifyNavigationBehaviorを適用します。
こんな感じです。
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms" xmlns:navigationSample="clr-namespace:NavigationSample;assembly=NavigationSample" prism:ViewModelLocator.AutowireViewModel="True" x:Class="NavigationSample.Views.A3Page" Title="A3Page"> <ContentPage.Behaviors> <navigationSample:NotifyNavigationBehavior/> </ContentPage.Behaviors>
ViewModel
続いてViewに対応するViewModel側を修正します。
こんな感じです。
public class A1PageViewModel : BindableBase, IAppearingAware, IDisappearingAware { public void OnAppearing() { } public void OnDisappearing() { }
画面への入場をハンドルしたい場合はIAppearingAwareを、画面からの退場をハンドルしたい場合にはIDisappearingAwareを実装しましょう。
以上です。
簡単ですね!
作り方
細かい説明の前に、Github側にコードを公開していますのでそちらを紹介します。
リンク先のNavigationSample.slnを参照ください。
なお、今回はEventToCommandBehaviorを紹介した際に利用したBindableBehaviorを利用しています。
そちらの解説は省略しますので、気になる方はリンク先も合わせてご覧ください。
さて、今回は2つのインターフェースと1つのクラスを作成しています。
- IAppearingAwareインターフェース
- IDisappearingAwareインターフェース
- NotifyNavigationBehaviorクラス
です。
それぞれ順次見ていきましょう。
IAppearingAware
画面入場時のイベントを受け取るためのインターフェースです。
public interface IAppearingAware { void OnAppearing(); }
説明は、、、不要ですね。
IDisappearingAware
画面退場時のイベントを受け取るためのインターフェースです。
public interface IDisappearingAware { void OnDisappearing(); }
何も言うまい。
NotifyNavigationBehavior
さて、主役の登場です。
まずはコードを見てみましょう。
public class NotifyNavigationBehavior : BindableBehavior<Page> { protected override void OnAttachedTo(Page bindable) { base.OnAttachedTo(bindable); bindable.Appearing += OnAppearing; bindable.Disappearing += OnDisappearing; } protected override void OnDetachingFrom(Page bindable) { bindable.Disappearing -= OnDisappearing; bindable.Appearing -= OnAppearing; base.OnDetachingFrom(bindable); } private void OnAppearing(object sender, EventArgs eventArgs) { (AssociatedObject.BindingContext as IAppearingAware)?.OnAppearing(); } private void OnDisappearing(object sender, EventArgs eventArgs) { (AssociatedObject.BindingContext as IDisappearingAware)?.OnDisappearing(); } }
そんな難しいことはしていませんね。
OnAttachedToでPageにアタッチされた際に、PageのAppearingイベントとDisappearingメソッドへイベントハンドラを登録し、OnDetachingFromで登録したハンドラを削除します。
OnAppearingとOnDisappearingの中ではアタッチしているPageのBindingContextがそれぞれ対応するインターフェースを実装していた場合に、対応するメソッドを呼び出します。
これだけです。
さて、画面遷移がらみのイベントハンドリングはもう一つ、以下のエントリーも書いていますので良かったら見てみてください。
というわけで、今回はこれまで。
それではまた!