前回は画面遷移の時に指定するViewの名前を文字列で指定すると,バグの混入確立がUPするということで,nameofを使って対処するやり方を確認しました。今回は画面遷移の時に,引数が必要な場合の書き方を確認していきたいと思います。
引数を渡す側
引数を渡す側は,NavigationService.NavigateAsyncを記述するときに,NavigationParametersを渡す必要があります。NavigationParametersはstringのKeyとobject型の任意の値をセットにして渡します。今回はtitleというKeyで「XXXX」という文字列と引数として渡してみようと思います。
private void PageBShow() { var param = new NavigationParameters { {"title","XXXX" } }; NavigationService.NavigateAsync(nameof(PageBView), param); }
NavigationParametersのインスタンス「param」を生成して,titleというKeyとXXXX等文字のValueをセットにしたパラメータを作成して,NavigateAsyncの第2引数に渡しています。
引数をもらう側
引数をもらう側のPageBViewを見ていきましょう。
using Prism.Mvvm; namespace BlankApp1.ViewModels { public class PageBViewModel : BindableBase { public PageBViewModel() { } } }
まず,PageBViewModelは現在BindableBaseを継承していますが,MainPageViewModelと同じようにViewModelBaseを継承したほうが便利なので,変更します。
using Prism.Mvvm; using Prism.Navigation; namespace BlankApp1.ViewModels { public class PageBViewModel : ViewModelBase { public PageBViewModel(INavigationService navigationService) : base(navigationService) { } } }
ViewModelBaseに変更するとコンストラクタにINavigationServiceを指定していないためコンパイルエラーになります。これはMainPageViewModelを参考にしてコンストラクタの引数にINavigationServiceを記述します。Usingが不足しているとコンパイルが通らないため,「using Prism.Navigation;」を追加します。
OnNavigationToをコピー
PageBViewModelはViewModelBaseを継承するように変更しました。ViewModelBaseのソースコードを確認すると,OnNavigatedFrom,OnNavigatedTo,OnNavigatingToというvirtualメソッドが存在しています。語尾がToになっている2つは画面が表示される前と後に動作するメソッドです。今回は画面遷移前にパラメータを受け取りたいのでOnNavigatingToが動作するときにパラメータを受け取ります。OnNavigatingToのメソッドをコピーしてPageBViewModelに貼り付けます。
using Prism.Mvvm; using Prism.Navigation; namespace BlankApp1.ViewModels { public class PageBViewModel : ViewModelBase { public PageBViewModel(INavigationService navigationService) : base(navigationService) { } public override void OnNavigatingTo(INavigationParameters parameters) { Title = parameters["title"].ToString(); } } }
OnNavigatingToはViewModelBaseのvirtualメソッドなので,継承先のクラスで上書きをする必要があるためPageBViewModel側ではoverrideを記述しておきます。これで画面遷移時にparametersに引数がわたってくるので,MainPageViewModelで指定したKeyで引数を受け取ります。MainPageViewModelは「title」というKeyで指定したのでparameters[“title”]を指定すれば値が取得できます。この値をViewModelのTitleプロパティにセットして,画面のタイトルにしています。
View側の設定:タイトルのバインディング
PageBview側で,Titleのバインディングが必要なので次のように記述します。
<?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" prism:ViewModelLocator.AutowireViewModel="True" x:Class="BlankApp1.Views.PageBView" Title="{Binding Title}"> <Label Text="Page b"/> </ContentPage>
これで,PageBViewModelで指定したTitleが画面に表示されるはずです。ここで一度実行してみましょう。
画面が表示されました。この状態で「NEXT PAGE」ボタンを押下します。
PageBが表示され,タイトルが「XXXX」になっていることが確認できました。
これでパラメータ渡しが成功していることが分かります。