主にプログラミング関連のメモ帳 ♪(✿╹ヮ╹)ノ
書いてあるコードは自己責任でご自由にどうぞ。記事本文の無断転載は禁止です。
2015/11/22
Prism を使っていて、画面遷移をする際に、ページ全体を遷移するんじゃなく、
SplitView の Content の部分だけ画面遷移させるにはどうするんだろう?ということで。
ちなみに、 Prism を使わず、コードビハインドに直接書いての方法は、サンプル集にあります。
毎度のごとく、もしかしたら間違ってる/もっといい方法があるかもしれないので、
何かあったら教えてください。
SplitView.Content = rootFrame; // rootFrame は App.xaml.cs で生成したやつ。
追記開始
github.com
普通にサンプルありました。
後日気がついたのですが、間違ってました。
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
の内部だけ遷移することが可能となります。
実際のプロジェクトはこちら。