NavigationViewを使う

もくじ
https://tera1707.com/entry/2022/02/06/144447#WinUI3

やりたいこと

Xaml-Controls-Gallery をダウンロードして動かせば、動作も見れるしサンプルコードも手に入るが、自分でも動きを簡単に試したい。

できあがり

こういう画面をつくる。

画面左の項目を押すと、画面右側が、それに対応する画面に遷移するようなイメージ。

サンプルコード

メイン画面

NavigationView を持っているウインドウ。

<Window
    x:Class="App3.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App3"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d">

    <Grid>
        <NavigationView x:Name="nvSample" SelectionChanged="nvSample_SelectionChanged" PaneDisplayMode="Left" IsSettingsVisible="False">
            <NavigationView.MenuItems>
                <NavigationViewItem Icon="Emoji2" Content="Page1" Tag="SamplePage1" />
                <NavigationViewItemSeparator />
                <NavigationViewItem Icon="Save" Content="Page2" Tag="SamplePage2" />
            </NavigationView.MenuItems>
            <NavigationView.FooterMenuItems>
                <NavigationViewItem Icon="Save" Content="Page3" Tag="SamplePage3" />
            </NavigationView.FooterMenuItems>
            <Frame x:Name="contentFrame"/>
        </NavigationView>        
    </Grid>    
</Window>
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media.Animation;

namespace App3
{
    public sealed partial class MainWindow : Window
    {
        public MainWindow()
        {
            this.InitializeComponent();
        }

        private void nvSample_SelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args)
        {
            if (args.SelectedItemContainer != null)
            {
                if ((string)args.SelectedItemContainer?.Tag == "SamplePage1")
                {
                    contentFrame.Navigate(typeof(BlankPage1), null, new SlideNavigationTransitionInfo() { Effect = SlideNavigationTransitionEffect.FromRight });
                }
                else if ((string)args.SelectedItemContainer?.Tag == "SamplePage2")
                {
                    contentFrame.Navigate(typeof(BlankPage2), null,  new SlideNavigationTransitionInfo() { Effect = SlideNavigationTransitionEffect.FromLeft });
                }
                else
                {
                    contentFrame.Navigate(typeof(BlankPage3), null, new EntranceNavigationTransitionInfo() );
                }
            }
        }
    }
}

中身の画面(ページ)

メイン画面の中で、画面遷移を行うページ。 これとほぼ同じページを3つ作って遷移させる。(BlankPage1~3)

<Page
    x:Class="App3.BlankPage1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App3"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Grid>
        <Image Source="Assets/MyImage1.png"/>
    </Grid>
</Page>

試したこと

NavigationViewMenuItemsに、NavigationViewItemを入れると、メニューの項目を入れることができる。→例でいうとPage1と2。 FooterMenuItemsに入れると、メニューの後ろの方に、メニューの項目を入れることができる。→例でいうとPage3

            <NavigationView.MenuItems>
                <NavigationViewItem Icon="Emoji2" Content="Page1" Tag="SamplePage1" />
                <NavigationViewItemSeparator />
                <NavigationViewItem Icon="Save" Content="Page2" Tag="SamplePage2" />
            </NavigationView.MenuItems>

NavigationView にFrameをセットして、FrameのNavigate()`メソッドを使って、コードから画面遷移を行うことができる。

contentFrame.Navigate(typeof(BlankPage1), null, new SlideNavigationTransitionInfo() { Effect = SlideNavigationTransitionEffect.FromRight });

BlankPage1が、自分で作ったページのクラス。ページは、プロジェクトに下記の新規項目を追加して作る。

Navigate()メソッドの第三引数にNavigationTransitionInfoクラスの派生クラスを入れてやると、画面遷移の際のエフェクトを指定できる。 (SlideNavigationTransitionInfoは左右からシュンと出てくる、EntranceNavigationTransitionInfoは下からシュンと出てくる、など)

NavigationViewItemIconプロパティには、シンボル名をセットするか、segoeフォントの文字をセットできる。 シンボル名はこちら。
segoeでの書き方はこちら。

NavigationViewSelectionChangedハンドラで、ボタンを押されたことを検知できる。 ‘NavigationViewItem‘のTagに指定したオブジェクト(文字列)を受け取ることができるので、それでどのボタンを押されたか判別して、遷移先の画面を切り替えできる。

private void nvSample_SelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args)
{
    if (args.SelectedItemContainer != null)
    {
        if ((string)args.SelectedItemContainer?.Tag == "SamplePage1")
        {
            contentFrame.Navigate(typeof(BlankPage1), null, new SlideNavigationTransitionInfo() { Effect = SlideNavigationTransitionEffect.FromRight });
        }
        else if ((string)args.SelectedItemContainer?.Tag == "SamplePage2")
        {
            contentFrame.Navigate(typeof(BlankPage2), null,  new SlideNavigationTransitionInfo() { Effect = SlideNavigationTransitionEffect.FromLeft });
        }
        else
        {
            contentFrame.Navigate(typeof(BlankPage3), null, new EntranceNavigationTransitionInfo() );
        }
    }
}

参考

NavigationView とは

docs.microsoft.com

NavigationView クラス(本体)

docs.microsoft.com

NavigationViewItem クラス(中身)

docs.microsoft.com

Xaml-Controls-Gallery (WinUI3で作れるものを試せるMS公式アプリ)

github.com

iconにセットできるもの

docs.microsoft.com

参考書

WinUI3

WinUI3でアプリを作ろうと思ったときのとっかかりによかった。 msdocsに書いてある情報を、体系的に、順番に読みたいな、というときによいかも。(ただし英語)
この本で分からなかった、かゆいところに手が届かなかった部分を私は記事にしてる感じ。

C#①

表紙に書いてある通り、教科書として最適。 これからC#を勉強したいけど、ネットだけで勉強するのは効率が悪いから体系的に学べる本が欲しいときや、 ちょっとC#を勉強してコード書けるようになったけど、もう少し広く深く知りたいなというときによいと思う。
私は仕事で触れるコードを軸に、基本ネットで断片的にC#を学んだので、その知識の隙間を埋めて枝葉を広げるためにとても分かりやすかった。

C#②

C#の文法的に色々できるのは分かったが、いざ実装するときに、わかったことを使ってどう実装すればいいのか?と悩んだときに指針になりそうな本。
「プロパティ等の名前の付け方、どうすればいい?」「情報をクラス外部に見せるときに、プロパティにすべき?メソッドにすべき?」「異常だと判定したいとき、どんなときにどんな例外をスローすべき?」などなど、勉強になる部分が山ほどあった。
私のように「コードは書くけどこれであってるのか自信がない、レビューで指摘されるのが嫌だ、実装時の(心の)よりどころが欲しい」という人に最適。