WPF_NavigationServiceでページ遷移

NavigationService

WPFのページ遷移では、NavigationWindow、Frame、NavigationServiceなどといったコントロールやクラスが用意されてます。

Frameにpage.xaml割り当てることでSPA(SimglePageApplication)の構造を作ることができます。


実装例

ファイル構成は下記の通りです。


- MainWindow.xaml
   `--- MainWindow.xaml.cs
- MainWindowViewModel.cs
- pages/
   |--- Page1.xaml
   |--- Page2.xaml
   `--- Page3.xaml

MainWindow.xaml


<Window x:Class="WpfPrismMvvm.MainWindow"
        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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        Title="MainWindow" Height="400" Width="600">

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="32"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="32"/>
        </Grid.RowDefinitions>
        <StackPanel Orientation="Horizontal" Background="DimGray">
            <TextBlock Margin="10,0,0,0" VerticalAlignment="Center" Text="フレーム" Foreground="White"/>
        </StackPanel>
        
        <Frame Grid.Row="1" NavigationUIVisibility="Hidden" Name="myFrame" />

        <StackPanel Orientation="Horizontal" Background="DimGray" Grid.Row="2">
            <Button Name="prevButton" Content="Prev" HorizontalAlignment="Left"
                    VerticalAlignment="Center" Width="50" Margin="10,0,0,0"
                    Command="{Binding PrevButtonClickedCommand}" />
            <Button Name="nextButton" Content="Next" HorizontalAlignment="Left"
                    VerticalAlignment="Center" Width="50"
                    Command="{Binding NextButtonClickedCommand}" />
        </StackPanel>
    </Grid>
</Window>

MainWindow.xaml.cs

frameをViewModelへ登録するようにします。


using System.Windows;

namespace WpfPrismMvvm
{
    /// <summary>
    /// MainWindow.xaml の相互作用ロジック
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            // フレームのNavigationServiceを渡す
            MainWindowViewModel vm = new MainWindowViewModel(this.myFrame.NavigationService);
            this.DataContext = vm;
        }
    }
}

MainWindowViewModel.cs

navigationService.Navigate()に相対パスでxamlファイルを指定してページ遷移します。


using Prism.Commands;
using Prism.Mvvm;
using System;
using System.Collections.Generic;
using System.Windows.Navigation;

namespace WpfPrismMvvm
{
    public class MainWindowViewModel : BindableBase
    {
        private List<Uri> _uriList = new List<Uri>() {
            new Uri("pages/Page1.xaml", UriKind.Relative),
            new Uri("pages/Page2.xaml", UriKind.Relative),
            new Uri("pages/Page3.xaml", UriKind.Relative),
        };
        private NavigationService navigationService;

        public DelegateCommand NextButtonClickedCommand { get; private set; }

        public DelegateCommand PrevButtonClickedCommand { get; private set; }


        public MainWindowViewModel(NavigationService navigationService)
        {
            this.navigationService = navigationService;
            navigationService.Navigate(_uriList[0]);

            NextButtonClickedCommand = new DelegateCommand(LoadNextPage);
            PrevButtonClickedCommand = new DelegateCommand(LoadPrevPage);
        }

        private void LoadNextPage()
        {
            if (navigationService.CurrentSource == null)
            {
                navigationService.Navigate(_uriList[0]);
                return;
            }

            switch(navigationService.CurrentSource.ToString())
            {
                case "pages/Page1.xaml":
                    navigationService.Navigate(_uriList[1]);
                    break;
                case "pages/Page2.xaml":
                    navigationService.Navigate(_uriList[2]);
                    break;
                case "pages/Page3.xaml":
                default:                    
                    break;
            }
        }

        private void LoadPrevPage()
        {
            if (navigationService.CurrentSource == null)
            {
                return;
            }

            switch (navigationService.CurrentSource.ToString())
            {
                case "pages/Page3.xaml":
                    navigationService.Navigate(_uriList[1]);
                    break;
                case "pages/Page2.xaml":
                    navigationService.Navigate(_uriList[0]);
                    break;
                case "pages/Page1.xaml":
                default:
                    break;
            }
        }
    }
}

Page1.xaml

ページ部品となります。ページ遷移が分かりやすいように背景色を変えています。


<Page x:Class="WpfPrismMvvm.pages.Page1"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:local="clr-namespace:WpfPrismMvvm.pages"
      mc:Ignorable="d" 
      d:DesignHeight="200" d:DesignWidth="300"
      Title="Page1">

    <Grid Background="Blue">
        <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="ページ 1"/>
    </Grid>
</Page>

Page2.xaml

ページ部品となります。ページ遷移が分かりやすいように背景色を変えています。


<Page x:Class="WpfPrismMvvm.pages.Page2"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:local="clr-namespace:WpfPrismMvvm.pages"
      mc:Ignorable="d" 
      d:DesignHeight="200" d:DesignWidth="300"
      Title="Page2">

    <Grid Background="Yellow">
        <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="ページ 2"/>
    </Grid>
</Page>

Page3.xaml

ページ部品となります。ページ遷移が分かりやすいように背景色を変えています。


<Page x:Class="WpfPrismMvvm.pages.Page3"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:local="clr-namespace:WpfPrismMvvm.pages"
      mc:Ignorable="d" 
      d:DesignHeight="240" d:DesignWidth="360"
      Title="Page3">

    <Grid Background="Red">
        <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="ページ 3"/>
    </Grid>
</Page>


関連ページ