这里是借助三方UI框架实现了,感兴趣的小伙伴可以看一下。
深色模式:
浅色模式:
这里主要使用了以下三个包:
MahApps.Metro:UI库,提供菜单导航和其它控件
实现步骤: 1、使用BlurWindow放置一个窗口
1 <tianxia:BlurWindow x:Class="GameOptimizerTool.MainWindow"
2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
9 xmlns:tianxia="clr-namespace:TianXiaTech"
10 mc:Ignorable="d"
11 Title="工具箱" Height="650" Width="1100" TitleForeground="{DynamicResource MahApps.Brushes.Text}" Icon="logo.png" Background="{DynamicResource MahApps.Brushes.ThemeBackground}">
12 <Grid>
13 </Grid>
14 </tianxia:BlurWindow>
这里的一些颜色使用了动态资源 ,以便实现深色和浅色模式的切换。
2、引入 XAML命名空间前缀
1 xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls"
2 xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
3 xmlns:iconPacks="http://metro.mahapps.com/winfx/xaml/iconpacks"
3、放置HamburgerMenu控件
通过设置HamburgerMenu.ItemsSource属性,可以设置菜单项
通过设置HamburgerMenu.OptionsItemsSource属性,可以增加设置项,设置项会显示在左下角
注意:这里我们需要设置控件的控件模板,否则 会显示异常
1 <mah:HamburgerMenu x:Name="HamburgerMenuControl"
2 CompactPaneLength="48"
3 OpenPaneLength="70"
4 HamburgerWidth="48"
5 IsPaneOpen="True"
6 ItemInvoked="HamburgerMenuControl_OnItemInvoked"
7 ItemTemplate="{StaticResource MenuItemTemplate}"
8 OptionsItemTemplate="{StaticResource MenuItemTemplate}"
9 SelectedIndex="0"
10 Style="{StaticResource MahApps.Styles.HamburgerMenu.Ripple}"
11 VerticalScrollBarOnLeftSide="False">
12 <!--Items-->
13 <mah:HamburgerMenu.ItemsSource>
14 <mah:HamburgerMenuItemCollection>
15 <mah:HamburgerMenuIconItem Icon="{iconPacks:Material Kind=Home}" Label="首页">
16 <mah:HamburgerMenuIconItem.Tag>
17 <local:HomeView />
18 </mah:HamburgerMenuIconItem.Tag>
19 </mah:HamburgerMenuItemCollection>
20 </mah:HamburgerMenu.ItemsSource>
21
22 <!--设置-->
23 <mah:HamburgerMenu.OptionsItemsSource>
24 <mah:HamburgerMenuItemCollection>
25 <mah:HamburgerMenuIconItem Icon="{iconPacks:Material Kind=Cog}" Label="设置">
26 <mah:HamburgerMenuIconItem.Tag>
27 <local:OptimizerView />
28 </mah:HamburgerMenuIconItem.Tag>
29 </mah:HamburgerMenuIconItem>
30 </mah:HamburgerMenuItemCollection>
31 </mah:HamburgerMenu.OptionsItemsSource>
32
33 <mah:HamburgerMenu.ContentTemplate>
34 <DataTemplate DataType="{x:Type mah:HamburgerMenuIconItem}">
35 <Grid Margin="20 0 10 0">
36 <Grid.RowDefinitions>
37 <RowDefinition Height="Auto" />
38 <RowDefinition Height="*" />
39 </Grid.RowDefinitions>
40 <!--标题文本,如果需要大标题显示,取消注释这段代码-->
41 <TextBlock Grid.Row="0"
42 Margin="0 15 0 5"
43 Padding="0"
44 FontFamily="{DynamicResource MahApps.Fonts.Family.Header}"
45 FontSize="{DynamicResource MahApps.Font.Size.Header}"
46 Foreground="{DynamicResource MahApps.Brushes.Text}"
47 Text="{Binding Label}" />
48 <ScrollViewer Grid.Row="1"
49 Focusable="False"
50 HorizontalScrollBarVisibility="Disabled"
51 VerticalScrollBarVisibility="Auto">
52 <ContentControl Content="{Binding Tag}" Focusable="False" />
53 </ScrollViewer>
54 </Grid>
55 </DataTemplate>
56 </mah:HamburgerMenu.ContentTemplate>
57
58 </mah:HamburgerMenu>
4、设置HamburgerMenu控件菜单项的样式
我们直接放到窗口资源 里
1 <tianxia:BlurWindow.Resources>
2 <ResourceDictionary>
3 <!--左侧菜单的样式-->
4 <DataTemplate x:Key="MenuItemTemplate" DataType="{x:Type mah:HamburgerMenuIconItem}">
5 <Grid Height="40">
6 <Grid.ColumnDefinitions>
7 <ColumnDefinition Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type mah:HamburgerMenu}}, Path=CompactPaneLength}" />
8 <ColumnDefinition />
9 </Grid.ColumnDefinitions>
10 <ContentControl Grid.Column="0"
11 HorizontalAlignment="Center"
12 VerticalAlignment="Center"
13 Content="{Binding Icon}"
14 Focusable="False"
15 IsTabStop="False" />
16 <TextBlock Grid.Column="1"
17 VerticalAlignment="Center"
18 FontSize="13"
19 Text="{Binding Label}" />
20 </Grid>
21 </DataTemplate>
22
23 <ObjectDataProvider x:Key="DisplayModeEnumValues"
24 MethodName="GetValues"
25 ObjectType="{x:Type mah:SplitViewDisplayMode}">
26 <ObjectDataProvider.MethodParameters>
27 <x:Type TypeName="mah:SplitViewDisplayMode" />
28 </ObjectDataProvider.MethodParameters>
29 </ObjectDataProvider>
30
31 <ObjectDataProvider x:Key="VisibilityEnumValues"
32 MethodName="GetValues"
33 ObjectType="{x:Type Visibility}">
34 <ObjectDataProvider.MethodParameters>
35 <x:Type TypeName="Visibility" />
36 </ObjectDataProvider.MethodParameters>
37 </ObjectDataProvider>
38
39 <Style x:Key="MahApps.Styles.ListBoxItem.HamburgerMenuItem.Ripple"
40 BasedOn="{StaticResource MahApps.Styles.ListBoxItem.HamburgerMenuItem}"
41 TargetType="{x:Type ListBoxItem}">
42 <Setter Property="Template">
43 <Setter.Value>
44 <ControlTemplate TargetType="{x:Type ListBoxItem}">
45 <Grid x:Name="RootGrid"
46 Background="Transparent"
47 RenderOptions.ClearTypeHint="{TemplateBinding RenderOptions.ClearTypeHint}">
48 <Border x:Name="Border"
49 Background="{TemplateBinding Background}"
50 BorderBrush="{TemplateBinding BorderBrush}"
51 BorderThickness="{TemplateBinding BorderThickness}"
52 SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
53 <Grid Margin="{TemplateBinding BorderThickness}">
54 <Grid HorizontalAlignment="Left"
55 VerticalAlignment="Center"
56 Visibility="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type mah:HamburgerMenu}}, Path=ShowSelectionIndicator, Mode=OneWay, Converter={StaticResource BooleanToVisibilityConverter}}">
57 <Rectangle x:Name="SelectionIndicator"
58 Width="{DynamicResource HamburgerMenuSelectionIndicatorThemeWidth}"
59 Height="{DynamicResource HamburgerMenuSelectionIndicatorThemeHeight}"
60 Fill="{TemplateBinding Foreground}"
61 Focusable="False"
62 Opacity="0.0" />
63 </Grid>
64 <materialDesign:Ripple x:Name="ContentPresenter"
65 Padding="{TemplateBinding Padding}"
66 HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
67 VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
68 Content="{TemplateBinding Content}"
69 ContentTemplate="{TemplateBinding ContentTemplate}"
70 ContentTemplateSelector="{TemplateBinding ContentTemplateSelector}"
71 Feedback="{DynamicResource MahApps.Brushes.Gray.MouseOver}"
72 Focusable="False"
73 SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
74 </Grid>
75 </Grid>
76 <ControlTemplate.Triggers>
77 <Trigger Property="IsSelected" Value="True">
78 <Setter TargetName="Border" Property="Background" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(mah:ItemHelper.SelectedBackgroundBrush), Mode=OneWay}" />
79 <Setter TargetName="ContentPresenter" Property="Foreground" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(mah:ItemHelper.SelectedForegroundBrush), Mode=OneWay}" />
80 <Setter TargetName="SelectionIndicator" Property="Fill" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(mah:ItemHelper.SelectedForegroundBrush), Mode=OneWay}" />
81 <Setter TargetName="SelectionIndicator" Property="Opacity" Value="1.0" />
82 </Trigger>
83 <MultiTrigger>
84 <MultiTrigger.Conditions>
85 <Condition Property="IsSelected" Value="True" />
86 <Condition Property="Selector.IsSelectionActive" Value="True" />
87 </MultiTrigger.Conditions>
88 <Setter TargetName="Border" Property="Background" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(mah:ItemHelper.ActiveSelectionBackgroundBrush), Mode=OneWay}" />
89 <Setter TargetName="ContentPresenter" Property="Foreground" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(mah:ItemHelper.ActiveSelectionForegroundBrush), Mode=OneWay}" />
90 <Setter TargetName="SelectionIndicator" Property="Fill" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(mah:ItemHelper.ActiveSelectionForegroundBrush), Mode=OneWay}" />
91 </MultiTrigger>
92
93 <MultiTrigger>
94 <MultiTrigger.Conditions>
95 <Condition Property="IsMouseOver" Value="True" />
96 <Condition Property="IsSelected" Value="True" />
97 </MultiTrigger.Conditions>
98 <Setter TargetName="Border" Property="Background" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(mah:ItemHelper.HoverSelectedBackgroundBrush), Mode=OneWay}" />
99 <Setter TargetName="ContentPresenter" Property="Foreground" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(mah:ItemHelper.HoverSelectedForegroundBrush), Mode=OneWay}" />
100 <Setter TargetName="SelectionIndicator" Property="Fill" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(mah:ItemHelper.HoverSelectedForegroundBrush), Mode=OneWay}" />
101 </MultiTrigger>
102 <MultiTrigger>
103 <MultiTrigger.Conditions>
104 <Condition Property="IsMouseOver" Value="True" />
105 <Condition Property="IsSelected" Value="False" />
106 </MultiTrigger.Conditions>
107 <Setter TargetName="Border" Property="Background" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(mah:ItemHelper.HoverBackgroundBrush), Mode=OneWay}" />
108 <Setter TargetName="ContentPresenter" Property="Foreground" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(mah:ItemHelper.HoverForegroundBrush), Mode=OneWay}" />
109 <Setter TargetName="SelectionIndicator" Property="Fill" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(mah:ItemHelper.HoverForegroundBrush), Mode=OneWay}" />
110 </MultiTrigger>
111
112 <Trigger Property="mah:ItemHelper.IsMouseLeftButtonPressed" Value="True">
113 <Setter TargetName="Border" Property="Background" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(mah:ItemHelper.MouseLeftButtonPressedBackgroundBrush), Mode=OneWay}" />
114 <Setter TargetName="ContentPresenter" Property="Foreground" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(mah:ItemHelper.MouseLeftButtonPressedForegroundBrush), Mode=OneWay}" />
115 <Setter TargetName="SelectionIndicator" Property="Fill" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(mah:ItemHelper.MouseLeftButtonPressedForegroundBrush), Mode=OneWay}" />
116 </Trigger>
117 <Trigger Property="mah:ItemHelper.IsMouseRightButtonPressed" Value="True">
118 <Setter TargetName="Border" Property="Background" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(mah:ItemHelper.MouseRightButtonPressedBackgroundBrush), Mode=OneWay}" />
119 <Setter TargetName="ContentPresenter" Property="Foreground" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(mah:ItemHelper.MouseRightButtonPressedForegroundBrush), Mode=OneWay}" />
120 <Setter TargetName="SelectionIndicator" Property="Fill" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(mah:ItemHelper.MouseRightButtonPressedForegroundBrush), Mode=OneWay}" />
121 </Trigger>
122
123 <Trigger Property="IsEnabled" Value="False">
124 <Setter TargetName="Border" Property="Background" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(mah:ItemHelper.DisabledBackgroundBrush), Mode=OneWay}" />
125 <Setter TargetName="ContentPresenter" Property="Foreground" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(mah:ItemHelper.DisabledForegroundBrush), Mode=OneWay}" />
126 <Setter TargetName="RootGrid" Property="Background" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Background, Mode=OneWay}" />
127 <Setter TargetName="SelectionIndicator" Property="Fill" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(mah:ItemHelper.DisabledForegroundBrush), Mode=OneWay}" />
128 </Trigger>
129 <MultiTrigger>
130 <MultiTrigger.Conditions>
131 <Condition Property="IsEnabled" Value="False" />
132 <Condition Property="IsSelected" Value="True" />
133 </MultiTrigger.Conditions>
134 <Setter TargetName="Border" Property="Background" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(mah:ItemHelper.DisabledSelectedBackgroundBrush), Mode=OneWay}" />
135 <Setter TargetName="ContentPresenter" Property="Foreground" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(mah:ItemHelper.DisabledSelectedForegroundBrush), Mode=OneWay}" />
136 <Setter TargetName="SelectionIndicator" Property="Fill" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=(mah:ItemHelper.DisabledSelectedForegroundBrush), Mode=OneWay}" />
137 </MultiTrigger>
138 </ControlTemplate.Triggers>
139 </ControlTemplate>
140 </Setter.Value>
141 </Setter>
142 <Setter Property="mah:ItemHelper.ActiveSelectionBackgroundBrush" Value="Transparent" />
143 <Setter Property="mah:ItemHelper.ActiveSelectionForegroundBrush" Value="{DynamicResource MahApps.Brushes.AccentBase}" />
144 <Setter Property="mah:ItemHelper.DisabledForegroundBrush" Value="{DynamicResource MahApps.Brushes.Gray}" />
145 <Setter Property="mah:ItemHelper.DisabledSelectedBackgroundBrush" Value="Transparent" />
146 <Setter Property="mah:ItemHelper.DisabledSelectedForegroundBrush" Value="{DynamicResource MahApps.Brushes.Gray}" />
147 <Setter Property="mah:ItemHelper.HoverBackgroundBrush" Value="{DynamicResource MahApps.Brushes.Gray.SemiTransparent}" />
148 <Setter Property="mah:ItemHelper.HoverSelectedBackgroundBrush" Value="{DynamicResource MahApps.Brushes.Gray.SemiTransparent}" />
149 <Setter Property="mah:ItemHelper.HoverSelectedForegroundBrush" Value="{DynamicResource MahApps.Brushes.AccentBase}" />
150 <Setter Property="mah:ItemHelper.SelectedBackgroundBrush" Value="Transparent" />
151 <Setter Property="mah:ItemHelper.SelectedForegroundBrush" Value="{DynamicResource MahApps.Brushes.AccentBase}" />
152 </Style>
153
154 <Style x:Key="MahApps.Styles.HamburgerMenu.Ripple"
155 BasedOn="{StaticResource MahApps.Styles.HamburgerMenu}"
156 TargetType="{x:Type mah:HamburgerMenu}">
157 <Setter Property="ItemContainerStyle" Value="{StaticResource MahApps.Styles.ListBoxItem.HamburgerMenuItem.Ripple}" />
158 <Setter Property="OptionsItemContainerStyle" Value="{StaticResource MahApps.Styles.ListBoxItem.HamburgerMenuItem.Ripple}" />
159 <Setter Property="PaneBackground" Value="{DynamicResource MahApps.Brushes.ThemeBackground}" />
160 <Setter Property="PaneForeground" Value="{DynamicResource MahApps.Brushes.Text}" />
161 <Setter Property="ShowSelectionIndicator" Value="True" />
162 </Style>
163
164 </ResourceDictionary>
165 </tianxia:BlurWindow.Resources>
5、增加菜单项切换时的事件处理程序
在放置HamburgerMenu控件时,设置了ItemInvoked事件
1 ItemInvoked="HamburgerMenuControl_OnItemInvoked"
事件处理程序如下:
1 private void HamburgerMenuControl_OnItemInvoked(object sender, MahApps.Metro.Controls.HamburgerMenuItemInvokedEventArgs args)
2 {
3 HamburgerMenuControl.Content = args.InvokedItem;
4 }
6、切换深色模式
MahApps.Metro提供了模式切换的功能,直接调用以下代码即可
1 private void Window_Loaded(object sender, RoutedEventArgs e)
2 {
3 ThemeManager.Current.ChangeThemeBaseColor(Application.Current, "Dark");
4 }
HamburgerMenu控件是如何实现的
这里内部其实是使用的ListBox,ListBox自身已经具备了切换事件和选中事件,所以在ListBox的基础上,加以封装,就能实现HamburgerMenu。
这里不做详细介绍,可以参考MahApps.Metro 源码里的Themes\HamburgerMenuTemplate.xaml 和Controls\HamburgerMenu里的文件。
最终效果