nuits.jp blog

C#, Xamarin, WPFを中心に書いています。Microsoft MVP for Development Technologies。

Prism for Xamarin.Forms入門 画面遷移をViewModelに通知するBehaviorを作ってみた

さて一つ前の記事で、PrismのINavigationAwareを代替するのに、PageクラスのAppearingイベントとDisappearingイベントが利用できる。
というお話をしました。

www.nuits.jp

今回はそれを簡便に実現するための方法を紹介したいと思います。

以前、イベントに反応してコマンドを実行する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側にコードを公開していますのでそちらを紹介します。

github.com

リンク先のNavigationSample.slnを参照ください。
なお、今回はEventToCommandBehaviorを紹介した際に利用したBindableBehaviorを利用しています。
そちらの解説は省略しますので、気になる方はリンク先も合わせてご覧ください。

さて、今回は2つのインターフェースと1つのクラスを作成しています。

  1. IAppearingAwareインターフェース
  2. IDisappearingAwareインターフェース
  3. 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がそれぞれ対応するインターフェースを実装していた場合に、対応するメソッドを呼び出します。
これだけです。

さて、画面遷移がらみのイベントハンドリングはもう一つ、以下のエントリーも書いていますので良かったら見てみてください。

www.nuits.jp

というわけで、今回はこれまで。
それではまた!