上記記事をPrism.Formsを使ってやるとどうなるだろうという奴です。
まず、Prism MasterDetailPage (Forms)でRootPageという名前のページを作ります。
続けて、メニュー部を担当するMenuPageをPrism ContentPage (Forms)で作ります。
Menuに表示するための要素を表すMenuItemクラスを作成しましょう。オリジナルと違うのはPrismの画面遷移は名前でやるので、PageTypeではなくPageNameを持たせてるところと、アイコンは用意するのがめんどくさいので諦めました。
namespace PrismUnityApp12.ViewModels { publicclass MenuItem { publicstring Title { get; set; } publicstring PageName { get; set; } } }
RootPageViewModelを作ってメニューを組み立てます。
publicclass RootPageViewModel : BindableBase { public ObservableCollection<MenuItem> Menus { get; } = new ObservableCollection<MenuItem> { new MenuItem { Title = "Contracts", PageName = "ContractsPage" }, new MenuItem { Title = "Leads", PageName = "LeadsPage" }, new MenuItem { Title = "Accounts", PageName = "AccountsPage" }, new MenuItem { Title = "Opportunities", PageName = "OpportunitiesPage" }, }; }
このメニューを表示するためのMenuPage.xamlを作ります。
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="PrismUnityApp12.Views.MenuPage" Title="Menu"> <StackLayout> <Label Text="Menu" FontSize="18" Margin="10,36,0,5"/> <ListView ItemsSource="{Binding Menus}" VerticalOptions="FillAndExpand" ItemSelected="ListViewMenu_ItemSelected"> <ListView.ItemTemplate> <DataTemplate> <ViewCell> <StackLayout Orientation="Horizontal"> <Label Text="{Binding Title}" HorizontalOptions="FillAndExpand" /> </StackLayout> </ViewCell> </DataTemplate> </ListView.ItemTemplate> </ListView> </StackLayout> </ContentPage>
MenuPageは、RootPage.MasterプロパティにセットするのでBindingContextはRootPageViewModelです。コードビハインドは以下のような感じです。
using PrismUnityApp12.ViewModels; using System; using Xamarin.Forms; namespace PrismUnityApp12.Views { publicpartialclass MenuPage : ContentPage { private RootPageViewModel ViewModel => this.BindingContext as RootPageViewModel; public MenuPage() { InitializeComponent(); } private async void ListViewMenu_ItemSelected(object sender, SelectedItemChangedEventArgs e) { await this.ViewModel.PageChangeAsync(e.SelectedItem as ViewModels.MenuItem); } } }
RootPageViewModelに以下のようなコードを追加して画面遷移対応させます。
using Prism.Mvvm; using Prism.Navigation; using System.Collections.ObjectModel; using System.Threading.Tasks; namespace PrismUnityApp12.ViewModels { publicclass RootPageViewModel : BindableBase { public ObservableCollection<MenuItem> Menus { get; } = new ObservableCollection<MenuItem> { new MenuItem { Title = "Contracts", PageName = "ContractsPage" }, new MenuItem { Title = "Leads", PageName = "LeadsPage" }, new MenuItem { Title = "Accounts", PageName = "AccountsPage" }, new MenuItem { Title = "Opportunities", PageName = "OpportunitiesPage" }, }; private INavigationService NavigationService { get; } privatebool isPresented; publicbool IsPresented { get { returnthis.isPresented; } set { this.SetProperty(refthis.isPresented, value); } } public RootPageViewModel(INavigationService navigationService) { this.NavigationService = navigationService; } public async Task PageChangeAsync(MenuItem menuItem) { await this.NavigationService.Navigate($"NavigationPage/{menuItem.PageName}"); this.IsPresented = false; } } }
Prism MasterDetailPage (Forms)をRootPageという名前で作って以下のように書きます。
<?xml version="1.0" encoding="utf-8" ?> <MasterDetailPage 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:Views="clr-namespace:PrismUnityApp12.Views;assembly=PrismUnityApp12" prism:ViewModelLocator.AutowireViewModel="True" x:Class="PrismUnityApp12.Views.RootPage" IsPresented="{Binding IsPresented, Mode=TwoWay}"> <MasterDetailPage.Master> <Views:MenuPage /> </MasterDetailPage.Master> <MasterDetailPage.Detail> <ContentPage Title="Dummy" /> <!-- Dummy --> </MasterDetailPage.Detail> </MasterDetailPage>
IsPresentedをViewModelとバインドするのを忘れずに。
あとは、AccountsPage, ContractsPage, LeadsPage, OpportunitiesPageを作ってApp.xaml.csで登録しておきます。
using Prism.Unity; using PrismUnityApp12.Views; using Xamarin.Forms; namespace PrismUnityApp12 { publicpartialclass App : PrismApplication { protectedoverride async void OnInitialized() { InitializeComponent(); await this.NavigationService.Navigate("/RootPage/NavigationPage/ContractsPage"); } protectedoverridevoid RegisterTypes() { this.Container.RegisterTypeForNavigation<RootPage>(); this.Container.RegisterTypeForNavigation<NavigationPage>(); this.Container.RegisterTypeForNavigation<ContractsPage>(); this.Container.RegisterTypeForNavigation<LeadsPage>(); this.Container.RegisterTypeForNavigation<AccountsPage>(); this.Container.RegisterTypeForNavigation<OpportunitiesPage>(); } } }
これで実行すると、以下のようになります。