WPF に搭載されている標準コントロールを見た目がオシャレな Material Design に変えてくれるパッケージがあります。
今回は、この Material Design のパッケージを使って、WPF でオシャレなメニュー画面を作成します。
画面の左端に配置されたハンバーガートグルボタンをクリックすると、メニューが左横からスライドインします。メニュートグルボタンをクリックすると、メニューが左横へスライドアウトして表示が消えます。
完成イメージがこちら。
オススメの参考書
C#の使い方が丁寧に解説しており、「基礎からしっかりと学びたい」という初心者の方にオススメの一冊です。サンプルコードも記載してあり、各章の最後に復習問題があるので理解度を確認しながら読み進めることができます。新しい C# のバージョンにも対応している書籍です。
Material Designの事前準備
まずは、WPF のプロジェクトに Material Design を適用させるために、「Material Design In XAML Toolkit」のインストールと App.xml にリソースの追加して初期設定を行います。
こちらの記事にインストール方法と初期設定について詳しく記載していますので、参考にしてみてください。
メニューの作成
メニューの作成には、DrawerHost
を使います。
DrawerHost
は、画面の上下左右からスライドインまたはスライドアウトしてくれるコントロールです。最近のアプリケーション(例えばYouTubeとか)ではよく使用されているので、このデザインを見たことがある方も多いことでしょう。
このデザインを作成するために、まずは XAML に以下のように記述します。
<materialDesign:DrawerHost>
</materialDesign:DrawerHost>
アプリのヘッダーを作成
ヘッダーとは、アプリケーションの上部に表示されている長方形のスペースのことです。人間の視線は上から下に動くので、初めに目がいくヘッダーは人に与える印象はとても大きいです。
Material Design In XAML Toolkit に含まれるColorZone
は、アプリのヘッダーに使われることが多いコントロールです。このColorZone
を先ほど記述したDrawerHost
タグの中に追加していきます。
ColerZone
を使ったサンプルが Material Design のデモアプリにあるので、このサンプルの中から好きなものを選択します。デモアプリの取得方法はこちらの記事の最後の項目に記載しています。
ここでは、デモアプリの一番上にあるサンプル(Invert the basic paper/body colours)をDrawerHost
のタグの中に追加します。
追加したコードは以下になります。
<materialDesign:DrawerHost>
<!-- デモアプリのColorZoneを追加する -->
<materialDesign:ColorZone Padding="16" Mode="Inverted">
<DockPanel>
<materialDesign:PopupBox DockPanel.Dock="Right" PlacementMode="BottomAndAlignRightEdges">
<ListBox>
<ListBoxItem Content="Hello World" />
<ListBoxItem Content="Nice Popup" />
<ListBoxItem Content="Goodbye" />
</ListBox>
</materialDesign:PopupBox>
<StackPanel Orientation="Horizontal">
<ToggleButton Style="{DynamicResource MaterialDesignHamburgerToggleButton}" />
<TextBlock
Margin="16,0,0,0"
VerticalAlignment="Center"
Text="Material Design In XAML Toolkit" />
</StackPanel>
</DockPanel>
</materialDesign:ColorZone>
</materialDesign:DrawerHost>
スライドイン・スライドアウトを作成
メニューをスライドさせるタグを追加します。上下左右のどこから出すのかを指定します。
例えば、メニューを左からスライドイン・スライドアウトさせたい場合は、DrawerHost.LeftDrawerContent
をDrawerHost
のタグの中に追加します。
DrawerHostを右からスライドさせたい場合は、DrawerHost.RightDrawerContent
を追加します。
<materialDesign:DrawerHost>
<!-- DrawerHost.RightDrawerContentを追加する -->
<materialDesign:DrawerHost.LeftDrawerContent>
</materialDesign:DrawerHost.LeftDrawerContent>
<!-- デモアプリのColorZoneを追加する -->
<materialDesign:ColorZone Padding="16" Mode="Inverted">
<DockPanel>
<materialDesign:PopupBox DockPanel.Dock="Right" PlacementMode="BottomAndAlignRightEdges">
<ListBox>
<ListBoxItem Content="Hello World" />
<ListBoxItem Content="Nice Popup" />
<ListBoxItem Content="Goodbye" />
</ListBox>
</materialDesign:PopupBox>
<StackPanel Orientation="Horizontal">
<ToggleButton Style="{DynamicResource MaterialDesignHamburgerToggleButton}" />
<TextBlock
Margin="16,0,0,0"
VerticalAlignment="Center"
Text="Material Design In XAML Toolkit" />
</StackPanel>
</DockPanel>
</materialDesign:ColorZone>
</materialDesign:DrawerHost>
メインの開閉制御
IsLeftDrawerOpen
でメインメニューのスライドイン・スライドアウトの制御をします。今回はMenuToggleButton
のIsChecked
と連動して開閉するようにします。IsChecked=true
ならスライドインし、IsChecked=false
ならスライドアウトします。
IsLeftDrawerOpen
にMenuToggleButton
のIsChecked
をバインディングします。MenuToggleButton
がクリックされると、メニューが左からスライドインするようになります。
<materialDesign:DrawerHost IsLeftDrawerOpen="{Binding ElementName=MenuToggleButton, Path=IsChecked}">
<materialDesign:DrawerHost.LeftDrawerContent>
</materialDesign:DrawerHost.LeftDrawerContent>
<!-- デモアプリのColorZoneを追加 -->
<materialDesign:ColorZone Padding="16" Mode="Inverted">
<DockPanel>
<materialDesign:PopupBox DockPanel.Dock="Right" PlacementMode="BottomAndAlignRightEdges">
<ListBox>
<ListBoxItem Content="Hello World" />
<ListBoxItem Content="Nice Popup" />
<ListBoxItem Content="Goodbye" />
</ListBox>
</materialDesign:PopupBox>
<StackPanel Orientation="Horizontal">
<ToggleButton x:Name="MenuToggleButton" Style="{DynamicResource MaterialDesignHamburgerToggleButton}" />
<TextBlock
Margin="16,0,0,0"
VerticalAlignment="Center"
Text="Material Design In XAML Toolkit" />
</StackPanel>
</DockPanel>
</materialDesign:ColorZone>
</materialDesign:DrawerHost>
上記のxamlで実行すると、こんな感じです。
このままでいいと思うのですが、ちょっといじってみます。
テーマ色の変更
背景色を青に変更したいので、App.xaml に追加したリソースのMergedDictionaries
タブ内にあるMaterialDesignColor
を Indigo に変更をします。ColorZone
タブ内にあるMode
をInvertedから PrimaryDark に変更します。これで色の変更ができます。
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/MaterialDesignColor.Indigo.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Accent/MaterialDesignColor.Lime.xaml" />
</ResourceDictionary.MergedDictionaries>
DrawerHost.LeftDrawerContent
タブの中にメインメニューで表示するラベルやテキスト、ボタンを配置すれば、完成です。
記事の先頭で紹介しているメニューの全コードは以下の通りです。
<materialDesign:DrawerHost IsLeftDrawerOpen="{Binding ElementName=MenuToggleButton, Path=IsChecked}">
<materialDesign:DrawerHost.LeftDrawerContent>
<DockPanel MinWidth="220">
<ToggleButton
Margin="16"
HorizontalAlignment="Right"
DockPanel.Dock="Top"
IsChecked="{Binding ElementName=MenuToggleButton, Path=IsChecked, Mode=TwoWay}"
Style="{StaticResource MaterialDesignHamburgerToggleButton}" />
<TextBox
x:Name="DemoItemsSearchBox"
Width="200"
Margin="16,4"
materialDesign:HintAssist.Hint="Search"
materialDesign:HintAssist.IsFloating="True"
materialDesign:TextFieldAssist.DecorationVisibility="Collapsed"
materialDesign:TextFieldAssist.HasClearButton="True"
materialDesign:TextFieldAssist.HasOutlinedTextField="True"
materialDesign:TextFieldAssist.TextFieldCornerRadius="4"
DockPanel.Dock="Top"
Text="{Binding SearchKeyword, UpdateSourceTrigger=PropertyChanged}" />
<StackPanel Margin="16,4">
<Button
Name="btnAccount"
Width="200"
Height="50"
Margin="0,4"
Style="{StaticResource MaterialDesignFlatButton}">
<DockPanel Width="200">
<materialDesign:PackIcon Kind="Account" />
<TextBlock Margin="10,0" Text="Account" />
</DockPanel>
</Button>
<Button
Name="btnSettings"
Width="200"
Height="50"
Margin="0,4"
Style="{StaticResource MaterialDesignFlatButton}">
<DockPanel Width="200">
<materialDesign:PackIcon Kind="Settings" />
<TextBlock Margin="10,0" Text="Settings" />
</DockPanel>
</Button>
</StackPanel>
</DockPanel>
</materialDesign:DrawerHost.RightDrawerContent>
<materialDesign:ColorZone
Padding="16"
materialDesign:ShadowAssist.ShadowDepth="Depth2"
Mode="PrimaryDark">
<DockPanel>
<materialDesign:PopupBox DockPanel.Dock="Right" PlacementMode="BottomAndAlignRightEdges">
<ListBox>
<ListBoxItem Content="Hello World" />
<ListBoxItem Content="Nice Popup" />
<ListBoxItem Content="Goodbye" />
</ListBox>
</materialDesign:PopupBox>
<StackPanel Orientation="Horizontal">
<ToggleButton
x:Name="MenuToggleButton"
AutomationProperties.Name="HamburgerToggleButton"
Click="MenuToggleButton_OnClick"
IsChecked="False"
Style="{DynamicResource MaterialDesignHamburgerToggleButton}" />
<TextBlock
Margin="16,0,0,0"
VerticalAlignment="Center"
Text="Material Design In XAML Toolkit" />
</StackPanel>
</DockPanel>
</materialDesign:ColorZone>
</materialDesign:DrawerHost>
まとめ
Material Design In XAML Toolkitを使って、オシャレなメイン画面を作成することができました。
次はメインメニューで選択したボタンに応じて画面が切り替わるアプリを作成しましょう。
以上、最後まで読んでいただきありがとうございました。