Prism を使っていて、画面遷移をする際に、ページ全体を遷移するんじゃなく、
SplitView の Content の部分だけ画面遷移させるにはどうするんだろう?ということで。
ちなみに、 Prism を使わず、コードビハインドに直接書いての方法は、サンプル集にあります。
毎度のごとく、もしかしたら間違ってる/もっといい方法があるかもしれないので、
何かあったら教えてください。
SplitView.Content = rootFrame; // rootFrame は App.xaml.cs で生成したやつ。
追記開始
普通にサンプルありました。
後日気がついたのですが、間違ってました。
SplitView.Content = rootFrame;
をしておく必要があります。
追記終了
基本的には、 MainPage
及び MainPageViewModel
でしか使わないだろうということで、
そういう感じに実装していきます。~~
まずはベースとなる SplitView を配置した MainPage.xaml
SplitView を使うのに、最低限と思われるものだけ配置しています。
<Page x:Class="PrismNavigation.Views.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="using:PrismNavigation.Views" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mvvm="using:Prism.Windows.Mvvm" mvvm:ViewModelLocator.AutoWireViewModel="True" mc:Ignorable="d"> <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Grid.RowDefinitions> <RowDefinition Height="48" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <StackPanel Grid.Row="0" Background="{StaticResource SystemControlBackgroundChromeMediumBrush}" Orientation="Horizontal"> <ToggleButton x:Name="HamburgerButton" Width="48" Height="48" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="{StaticResource ApplicationForegroundThemeBrush}"> <FontIcon Glyph="" /> </ToggleButton> <TextBlock VerticalAlignment="Center" Style="{StaticResource TitleTextBlockStyle}" Text="PrismNavigation" /> </StackPanel> <SplitView Grid.Row="1" IsPaneOpen="{Binding ElementName=HamburgerButton, Path=IsChecked}"> <SplitView.Pane> <RelativePanel> <ListBox> <ListBoxItem Tapped="{x:Bind ViewModel.NavigateToFirstPage}"> <TextBlock>First Page</TextBlock> </ListBoxItem> <ListBoxItem Tapped="{x:Bind ViewModel.NavigateToSecondPage}"> <TextBlock>Second Page</TextBlock> </ListBoxItem> </ListBox> </RelativePanel> </SplitView.Pane> <SplitView.Content> <Frame x:Name="Frame" /> </SplitView.Content> </SplitView> </Grid> </Page>
ポイントとしては、 SplitView.Content
の子として、 Frame
を追加しておくことです。
サンプルにもありますが、 Navigation で遷移させる場合には、 Frame
が必要です。
そして、 ViewModel
namespace PrismNavigation.ViewModels { public class MainPageViewModel : ViewModelBase { public INavigationService NavigationService { get; set; } public void NavigateToFirstPage() { this.NavigationService.Navigate("First", null); } public void NavigateToSecondPage() { this.NavigationService.Navigate("Second", null); } } }
普通に、 Prism で INavigationService
を使ったアプリと同じ感じです。
NavigationService
プロパティは、 public かつ readonly では無いものにしておきます。
次に、 MainPage.xaml
のコードビハインドをいじります。
ここで、 ViewModel の INavigationService
に対して設定を行います。
namespace PrismNavigation.Views { /// <summary> /// それ自体で使用できる空白ページまたはフレーム内に移動できる空白ページ。 /// </summary> public sealed partial class MainPage : Page { // x:Bind 用 public MainPageViewModel ViewModel => this.DataContext as MainPageViewModel; public MainPage() { this.InitializeComponent(); this.DataContextChanged += (sender, args) => this.ViewModel.NavigationService = new FrameNavigationService(new FrameFacadeAdapter(this.Frame), this.GetPageType, new SessionStateService()); } private Type GetPageType(string pageToken) { var pageName = this.GetType().Namespace + $".{pageToken}Page"; var view = Type.GetType(pageName); if (view == null) throw new ArgumentException($"Page {pageToken} is not found on {pageName}"); return view; } } }
Prism の AutoWire 機能で、 ViewModel が自動的に紐付けられるため、 DataContextChanged
でそれを検知し、
ViewModel の NavigationService
プロパティに、新しく作った Service を設定します。
ルートフレームを、 MainPage.xaml
で設定している Frame にすることで、 SplitView.Content
の内部だけ遷移することが可能となります。
実際のプロジェクトはこちら。