Material Design In XAML Tool Kit と TabControl で複数画面の切り替えをやってみた

Material Design In XAML Tool Kit に用意されている Colour Zones（ColourはColorの英語表記） と Drawer を使うと、今どきのナビゲーションメニューが実現できます。

今回は、タブコントロールに張り付けた複数の画面を、ナビゲーションメニューで切り替えるサンプルを作ってみました。

## 画面の動き

次のような画面です。Material Design In XAML Tool Kit のデモプログラムでは、ナビゲーションメニューを選ぶ度にメニューが閉じるので、閉じないようにしてみました。

![matelialdesigndrawer_sample.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3775985/7b3e743b-3231-434a-1fb8-3600fda0a2bb.gif)

## XAMLの階層構造

XAMLは下図の階層で構成しています。

![materialdesign_001.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3775985/b2cc25f5-6c1f-1199-457a-3241e83e7095.jpeg)

## XAMLのソースコード
```HTML
<Window x:Class="DesignTest.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"
        xmlns:local="clr-namespace:DesignTest"
        mc:Ignorable="d"
        xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
        TextElement.Foreground="{DynamicResource MaterialDesignBody}"
        Background="{DynamicResource MaterialDesignPaper}"
        TextElement.FontWeight="Medium"
        TextElement.FontSize="14"
        FontFamily="pack://application:,,,/MaterialDesignThemes.Wpf;component/Resources/Roboto/#Roboto"
        Title="MainWindow" Height="450" Width="800">

    <Grid>
        <DockPanel LastChildFill="True">
            <!-- 左Drawer を表示するためのトグルボタン -->
            <materialDesign:ColorZone
                DockPanel.Dock="Top"
                Padding="16"
                materialDesign:ElevationAssist.Elevation="Dp4"
                ClipToBounds="False"
                CornerRadius="10"
                Mode="PrimaryDark">
                <StackPanel Orientation="Horizontal">
                    <ToggleButton x:Name="OpenMenu"
                       Style="{StaticResource MaterialDesignHamburgerToggleButton}"
                       Click="OpenMenu_Click"/>

                    <TextBlock
                       Margin="16,0,0,0"
                       VerticalAlignment="Center"
                       Text="Material Design In XAML Toolkit のColour ZonesとDrawerを使った画面切り替えサンプル" />
                </StackPanel>
            </materialDesign:ColorZone>

            <DockPanel LastChildFill="True">
                <!-- Drawer全体のデザインを記述-->
                <materialDesign:DrawerHost
                    x:Name="DrawerHost"
                    DockPanel.Dock="Left"
                    DrawerClosing="DrawerHost_DrawerClosing"
                    BorderBrush="{DynamicResource MaterialDesignDivider}"
                    BorderThickness="2"
                    BottomDrawerBackground="{DynamicResource SecondaryHueLightBrush}"
                    BottomDrawerCornerRadius="20 20 0 0" >
                    <materialDesign:DrawerHost.Style>
                        <Style TargetType="materialDesign:DrawerHost" BasedOn="{StaticResource {x:Type materialDesign:DrawerHost}}" >
                            <Style.Triggers>
                                <DataTrigger Binding="{Binding IsChecked, ElementName=BackgroundToggle}" Value="True">
                                    <Setter  Property="OverlayBackground" Value="{DynamicResource PrimaryHueMidBrush}" />
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </materialDesign:DrawerHost.Style>

                    <!-- 左Drawerを表示させた時のメニューとメニューを選択した時の動作を記述-->
                    <materialDesign:DrawerHost.LeftDrawerContent>
                        <StackPanel Margin="16" >
                            <TextBlock  Margin="4" HorizontalAlignment="Center" Text="機能一覧" />
                            <!-- メニュー項目１ -->
                            <Button
                                Tag="0"
                                Margin="4"
                                HorizontalAlignment="Center"
                                Command="{x:Static materialDesign:DrawerHost.CloseDrawerCommand}"
                                CommandParameter="{x:Static Dock.Left}"
                                Content="テキストボックス"
                                Click="Button_Click"
                                Style="{StaticResource MaterialDesignFlatButton}" />
                            <!-- メニュー項目２ -->
                            <Button
                                Tag="1"
                                Margin="4"
                                HorizontalAlignment="Center"
                                Command="{x:Static materialDesign:DrawerHost.CloseDrawerCommand}"
                                Content="コンボボックス"
                                Click="Button_Click"
                                Style="{StaticResource MaterialDesignFlatButton}" />
                            <Button
                                Tag="2"
                                Margin="4"
                                HorizontalAlignment="Center"
                                Command="{x:Static materialDesign:DrawerHost.CloseDrawerCommand}"
                                Content="チェックボタン"
                                Click="Button_Click"
                                Style="{StaticResource MaterialDesignFlatButton}" />
                        </StackPanel>
                    </materialDesign:DrawerHost.LeftDrawerContent>
                </materialDesign:DrawerHost>

                <!-- メインコンテンツ -->
                <Grid>
                    <TabControl x:Name="ContentSelector">
                        <TabControl.ItemContainerStyle>
                            <Style TargetType="TabItem">
                                <Setter Property="Visibility" Value="Collapsed"/>
                            </Style>
                        </TabControl.ItemContainerStyle>
                        <TabItem >
                            <TextBox Width="200" Height="30" VerticalAlignment="Center" 
                                HorizontalAlignment="Center" 
                                TextAlignment="Center" 
                                Text="aaaaa" />
                        </TabItem>
                        <TabItem >
                            <ComboBox Width="200" Height="30" VerticalAlignment="Center" 
                                HorizontalAlignment="Center" 
                                Foreground="White"
                                Text="0000" >
                                <ComboBoxItem>1000</ComboBoxItem>
                                <ComboBoxItem>2000</ComboBoxItem>
                                <ComboBoxItem>3000</ComboBoxItem>
                            </ComboBox>
                       </TabItem>
                        <TabItem>
                            <CheckBox Width="200" Height="30" VerticalAlignment="Center" 
                                HorizontalAlignment="Center" 
                                Foreground="White"
                                Content="チェック項目１" />
                        </TabItem>
                    </TabControl>
                </Grid>
            </DockPanel>
        </DockPanel>
    </Grid>
</Window>
```

## C#のソースコード

```C#
using MaterialDesignThemes.Wpf;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace DesignTest
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        /// <summary>
        /// メニューが選択された時の処理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            ContentSelector.SelectedIndex = int.Parse(((Button)sender).Tag.ToString()??"");
        }

        /// <summary>
        /// ナビゲーションメニュー表示／非表示処理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OpenMenu_Click(object sender, RoutedEventArgs e)
        {
            DrawerHost.IsLeftDrawerOpen = OpenMenu.IsChecked ?? false;
        }

        /// <summary>
        ///  Drawerがクリックされた時の処理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DrawerHost_DrawerClosing(object sender, MaterialDesignThemes.Wpf.DrawerClosingEventArgs e)
        {
            DrawerHost.IsLeftDrawerOpen = OpenMenu.IsChecked ?? false;
        }
    }
}
```

## まとめ
スマホやWebアプリではよく使われているナビゲーションメニューですが、Windowsアプリで同じことを実現するとなると、かなり面倒です。

それが、Material Design In XAML ToolKit を使うと、すごく簡単に実現できてしまうので、有難いですね。


参考：[【WPF】 Material Design In XAML ToolKit を使ったナビゲーションメニュー４選](https://resanaplaza.com/2024/04/28/%e3%80%90wpf%e3%80%91-material-design-in-tool-kit-%e3%82%92%e4%bd%bf%e3%81%a3%e3%81%9f%e3%83%8a%e3%83%93%e3%82%b2%e3%83%bc%e3%82%b7%e3%83%a7%e3%83%b3%e3%83%a1%e3%83%8b%e3%83%a5%e3%83%bc%ef%bc%94/)