LoginSignup
10

More than 3 years have passed since last update.

[WPF] NavigationView(ナビゲーションビュー)を使う

Last updated at Posted at 2020-12-26

■概要

こんなの
000.png

■準備

🔗ここ を参考に「2. プロジェクト作成」から「5. テーマ適用」まで実施する。

※「2. プロジェクト作成」でプロジェクト名はWpfAppNaviView、フレームワークは.NET 5.0にした。
※「4. NuGet」は「ModernWpfUI」だけ入れればOK、「ModernWpf.MessageBox」は今回のサンプルでは使っていない。

■切り替えるページ追加

Pagesフォルダを作成し、その中に「追加」-「ページ (WPF)」で以下の名前でページを作成する。

  • AccountPage
  • BlankPage
  • DocumentPage
  • HomePage

010.png

■MainWindow

◇cs

enum定義。

MainWindow.xaml.cs


namespace WpfAppNaviView
{
    // 新しいページが増えたら追加
    public enum NaviIcon
    {
        Home,
        Account,
        Document,

        None,
    }

    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    

◇xaml

「Window」にxmlns:muxc="http://schemas.modernwpf.com/2019"を追加。
「Width」「Height」変更。
ResizeMode="CanResizeWithGrip"追加。

MainWindow.xaml
<Window
    x:Class="WpfAppNaviView.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:local="clr-namespace:WpfAppNaviView"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:muxc="http://schemas.modernwpf.com/2019"
    xmlns:ui="http://schemas.modernwpf.com/2019"
    Title="MainWindow"
    Width="1010"
    Height="700"
    ui:WindowHelper.UseModernWindowStyle="True"
    ResizeMode="CanResizeWithGrip"
    mc:Ignorable="d">

「Grid」を「NavigationView」に書き換え。
「NavigationViewItem」が選択変更されたら「Frame」のコンテンツを切り替えるように作っていく。
020_4.png
025_.png

「NavigationViewItem」の「Tag」に先ほど定義したenum値を設定。

MainWindow.xaml
    <muxc:NavigationView
        x:Name="NaviView"
        Header="★ヘッダー★"
        IsBackButtonVisible="Collapsed"
        IsSettingsVisible="False"
        IsTitleBarAutoPaddingEnabled="False"
        PaneDisplayMode="Auto"
        PaneTitle=""
        SelectionChanged="NaviView_SelectionChanged">
        <muxc:NavigationView.MenuItems>
            <muxc:NavigationViewItem
                Content="ホーム"
                Icon="Home"
                IsSelected="True"
                Tag="{x:Static local:NaviIcon.Home}" />
            <muxc:NavigationViewItem
                Content="アカウント"
                Icon="Contact"
                Tag="{x:Static local:NaviIcon.Account}" />
            <muxc:NavigationViewItem
                Content="ドキュメント"
                Icon="Page2"
                Tag="{x:Static local:NaviIcon.Document}" />
            <muxc:NavigationViewItem Content="ダウンロード" Icon="Download" />
            <muxc:NavigationViewItem Content="ミュージック" Icon="Audio" />
            <muxc:NavigationViewItem Content="ビデオ" Icon="Video" />
            <muxc:NavigationViewItem Content="編集" Icon="Edit" />
            <muxc:NavigationViewItem Content="ネットワーク" Icon="Globe" />
            <muxc:NavigationViewItem Content="メール" Icon="Mail" />
            <muxc:NavigationViewItem Content="すべてのアプリ" Icon="AllApps" />
            <muxc:NavigationViewItem Content="検索" Icon="Find" />
            <muxc:NavigationViewItem Content="計算" Icon="Calculator" />
            <muxc:NavigationViewItem Content="カレンダー" Icon="Calendar" />
            <muxc:NavigationViewItem Content="ゴミ箱" Icon="Delete" />
        </muxc:NavigationView.MenuItems>

        <ScrollViewer Margin="0,0,0,12">
            <ui:Frame x:Name="ContentFrame" Padding="12,0,12,12" />
        </ScrollViewer>
    </muxc:NavigationView>
</Window>

◇cs

enumと実際のページを紐づけるDictionaryを定義。
NavigationViewが選択変更されたら対応するページを表示する処理追加。

MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Windows;
using ui = ModernWpf.Controls;

namespace WpfAppNaviView
{
    // 新しいページが増えたら追加
    public enum NaviIcon
    {
        Home,
        Account,
        Document,

        None,
    }

    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        // 新しいページが増えたら追加
        private static IReadOnlyDictionary<NaviIcon, Type> _pages = new Dictionary<NaviIcon, Type>()
        {
            {NaviIcon.Home, typeof(Pages.HomePage)},
            {NaviIcon.Account, typeof(Pages.AccountPage)},
            {NaviIcon.Document, typeof(Pages.DocumentPage)},
            // 空ページ
            {NaviIcon.None, typeof(Pages.BlankPage)},
        };

        public MainWindow()
        {
            InitializeComponent();
        }

        private void NaviView_SelectionChanged(ui.NavigationView sender, ui.NavigationViewSelectionChangedEventArgs args)
        {
            try
            {
                var selectedItem = (ui.NavigationViewItem)args.SelectedItem;
                // Tag取得
                string iconName = selectedItem.Tag?.ToString();
                // ヘッダー設定
                sender.Header = iconName;

                if (Enum.TryParse(iconName, out NaviIcon icon))
                {
                    // 対応するページ表示
                    ContentFrame.Navigate(_pages[icon]);
                }
                else
                {
                    // 空ページ表示
                    ContentFrame.Navigate(_pages[NaviIcon.None]);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

    }
}

■各ページ内容

HomePage.xaml
<Page
    x:Class="WpfAppNaviView.Pages.HomePage"
    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="clr-namespace:WpfAppNaviView.Pages"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Title="HomePage"
    d:DesignHeight="450"
    d:DesignWidth="800"
    mc:Ignorable="d">

    <Grid>
        <TextBlock
            HorizontalAlignment="Center"
            VerticalAlignment="Center"
            FontSize="72"
            Text="ホーム" />
    </Grid>
</Page>
AccountPage.xaml
<Page
    x:Class="WpfAppNaviView.Pages.AccountPage"
    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="clr-namespace:WpfAppNaviView.Pages"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Title="AccountPage"
    d:DesignHeight="450"
    d:DesignWidth="800"
    mc:Ignorable="d">

    <Grid>
        <TextBlock
            HorizontalAlignment="Center"
            VerticalAlignment="Center"
            FontSize="72"
            Text="アカウント" />
    </Grid>
</Page>
DocumentPage.xaml
<Page
    x:Class="WpfAppNaviView.Pages.DocumentPage"
    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="clr-namespace:WpfAppNaviView.Pages"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Title="DocumentPage"
    d:DesignHeight="450"
    d:DesignWidth="800"
    mc:Ignorable="d">

    <StackPanel>
        <StackPanel.Resources>
            <Style TargetType="TextBlock">
                <Setter Property="FontSize" Value="72" />
                <Setter Property="Margin" Value="0,0,0,12" />
            </Style>
        </StackPanel.Resources>
        <TextBlock Text="ドキュメント1" />
        <TextBlock Text="ドキュメント2" />
        <TextBlock Text="ドキュメント3" />
        <TextBlock Text="ドキュメント4" />
        <TextBlock Text="ドキュメント5" />
        <TextBlock Text="ドキュメント6" />
        <TextBlock Text="ドキュメント7" />
        <TextBlock Text="ドキュメント8" />
    </StackPanel>
</Page>

まだ作っていないページはとりあえずこれを表示する。

BlankPage.xaml
<Page
    x:Class="WpfAppNaviView.Pages.BlankPage"
    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="clr-namespace:WpfAppNaviView.Pages"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Title="BlankPage"
    d:DesignHeight="450"
    d:DesignWidth="800"
    mc:Ignorable="d">

    <Grid />
</Page>

■実行

030.png

「ドキュメント」をクリック。
040.png

OSのテーマを「白」に変更。
050.png

ウィンドウサイズを小さくするとメニューがコンパクト化。
060.png

ハイコントラスト指定。
070.png

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10