MVVMパターンを大いに助けてくれるPrismフレームワークですが、意外とまだ情報が少ないです。
今回は基本的なところで、画面遷移と画面遷移によるパラメーターの受け渡しをさらっとご紹介します。
パラメーターの受け渡しに関しては、調べてもなかなか出てこなかった記憶があります。
Prismによる画面遷移
今回は簡単に下記のようなクラス構成で行っていきます。
※だいぶ端折りましたが、Prismのテンプレート(Blank App)でプロジェクトを作成し、Prismのアイテムテンプレートで「PrismContentPage1」を作成しています。
上記の流れで作成した場合、上記クラス構成の時点で「App.xaml.cs」の中身は下記のようになっています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
using Prism; using Prism.Ioc; using NavigationParameter.ViewModels; using NavigationParameter.Views; using Xamarin.Forms; using Xamarin.Forms.Xaml; using Prism.Unity; [assembly: XamlCompilation(XamlCompilationOptions.Compile)] namespace NavigationParameter { public partial class App : PrismApplication { /* * The Xamarin Forms XAML Previewer in Visual Studio uses System.Activator.CreateInstance. * This imposes a limitation in which the App class must have a default constructor. * App(IPlatformInitializer initializer = null) cannot be handled by the Activator. */ public App() : this(null) { } public App(IPlatformInitializer initializer) : base(initializer) { } protected override async void OnInitialized() { InitializeComponent(); await NavigationService.NavigateAsync("NavigationPage/MainPage"); } protected override void RegisterTypes(IContainerRegistry containerRegistry) { containerRegistry.RegisterForNavigation<NavigationPage>(); containerRegistry.RegisterForNavigation<MainPage>(); containerRegistry.RegisterForNavigation<PrismContentPage1>(); } } } |
この中で重要になるのが下記のコードです。
1 2 3 |
containerRegistry.RegisterForNavigation<NavigationPage>(); containerRegistry.RegisterForNavigation<MainPage>(); containerRegistry.RegisterForNavigation<PrismContentPage1>(); |
アプリ起動時にコンテナにページを登録しておくことで、ページ遷移の際にはそのコンテナからページが注入されているイメージです。
それでは実際の画面遷移を行うコードを見てみましょう。
下記のコードでページ遷移を実現することが出来ます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
using NavigationParameter.Views; using Prism.Navigation; using System.Threading.Tasks; namespace NavigationParameter.ViewModels { public class MainPageViewModel : ViewModelBase { public MainPageViewModel(INavigationService navigationService) : base(navigationService) { Title = "Main Page"; } public async Task NavigationToNextPage() { await base.NavigationService.NavigateAsync(typeof(PrismContentPage1).Name); } } } |
INavigationServiceのNavigateAsyncメソッドで遷移先のページの名前を指定することで遷移が可能です。
ただ一点気を付けることが、厳密にはページの遷移ではなく、モーダルのページを生成している、ということです。
なのでPrismを利用してアプリを作成する際には、ページ遷移の数がパフォーマンスに影響してくる可能性があります。
ちなみに下記のように絶対パスからの指定を行うと、それまで生成してきたページを全て破棄して新たにルートからのページが生成されるようです。
1 |
await base.NavigationService.NavigateAsync("/NavigationPage/MainPage/PrismContentPage1"); |
文字列の指定でも可能ですが、保守容易なコードにしていく為にもルートパスは定数かリソースなどで指定しておき、ページ名もtypeof(ページクラス).Nameなどで指定するのがいいと思われます。
Prismで画面遷移によるパラメーターの受け渡し
画面間でパラメーターの受け渡しを行うには、遷移元のページは下記のように記述します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
using NavigationParameter.Views; using Prism.Commands; using Prism.Navigation; using System.Threading.Tasks; namespace NavigationParameter.ViewModels { public class MainPageViewModel : ViewModelBase { public DelegateCommand Navigate { get; } public MainPageViewModel(INavigationService navigationService) : base(navigationService) { Title = "Main Page"; Navigate = new DelegateCommand(async () => await NavigationToNextPage()); } public async Task NavigationToNextPageContainParameter() { NavigationParameters parameters = new NavigationParameters(); parameters.Add("parameter", "受け渡し完了!"); await base.NavigationService.NavigateAsync(typeof(PrismContentPage1).Name, parameters); } } } |
NavigationParametersへの遷移パラメーターの追加は下記でも可能です。
1 |
NavigationParameters parameters = new NavigationParameters("parameter=受け渡し完了!"); |
遷移先のページでパラメーターを受け取るには、ViewModelBaseに実装されているINavigationAwareのメソッドを使います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
using Prism.Navigation; namespace NavigationParameter.ViewModels { public class PrismContentPage1ViewModel : ViewModelBase { public PrismContentPage1ViewModel(INavigationService navigationService) : base(navigationService) { } public override void OnNavigatedTo(NavigationParameters parameters) { base.OnNavigatedTo(parameters); var parameter = parameters.GetValue<string>("parameter"); } } } |
INavigationAwareインターフェースの挙動に関しては下記がとても参考になりました。
どうも、いまだかつてXamarinでアプリを一本も完成させたことのない初心者です。 本エントリーは[学生さん・初心者さん大歓迎!]Xamarin Advent Calendar 2016の12日目のエントリーとして投稿しました。 前日はbetatさんのグッとくる Xamarin Studio のショートカット・小技集 翌日はaki_lua87さんの[Xamarin.Forms]各プラットフォーム固有機能からFormsで作成したViewを表示するです! という訳で、今回はPrism for Xamarin.FormsでNavigationPageを利用して画面遷移を実装した場合の、詳細な情報を調…
とくに各メソッドがどのタイミングで動くか、は描画に大きく影響してきます。
ちょっとだけ書いておくと、受け取ったパラメーターで例えばリストデータを引き当てる場合、描画にはObservableCollectionではなく、BindableなList型のプロパティを使う必要がある、などです。
意外とObservableCollectionも万能ではありませんね。
まとめ
- Prismでの画面遷移はINavigationServiceのNavigateAsyncを使う。
- Prismでのパラメーター受け渡しはNavigateAsyncの第2引数にNavigationParametersを渡し、遷移先ではINavigationAwareのメソッドで受け取る。
- ObservableCollectionを信用しまくってるとハマる。
以上です。
スポンサーリンク