不同于Windows 8应用,Windows 10引入了“汉堡菜单”这一导航模式。说具体点,就拿官方的天气应用来说,左上角三条横杠的图标外加一个SplitView控件组成的这一导航模式就叫“汉堡菜单”。

  本文讨论的是如何实现官方的这一样式(点击后左侧出现一个填充矩形),普通实现网上到处都是,有需要的朋友自己百度下吧。

  下面将介绍两种不同的实现方法,第一种最简单的方法是直接使用 Template 10 模板,第二种就是纯手写了。

  若有什么不正确的地方望指正,大家共同讨论。

  1. Template 10 模板

  使用 Template 10 模板可以快速建立出应用的框架,简单快捷。(帮助文档 https://github.com/Windows-XAML/Template10/wiki )

  要使用 Template 10 首先点击 Visual Studio “工具”菜单中的“扩展与更新”,搜索并安装 Template 10(简化搜索可以直接输入t10)

  安装完成需要重启,重启后按下图找到项目模板新建即可,使用很简单,帮助文档连接也在上方给出。

  2. 手写

  先分析一下界面的构成,暂时不看标题栏,由一个设置了 Canvas.ZIndex 的 Button 和一个 SplitView 构成。SplitView.Pane 中又包含了两个ListView(一级菜单和二级菜单)。ListView 里的每个 Item 又由 Rectangle,FontIcon,TextBlock 组成。见下图

  构成清晰之后实现的思路大概也就清晰了。下面给一个简单的Demo,解决方案结构如下。(GitHub https://github.com/ZhangGaoxing/uwp-demo/tree/master/HamburgerDemo

  先创建一个NavMenuItem类

using System;
using System.ComponentModel;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Media; namespace HamburgerDemo
{
class NavMenuItem : INotifyPropertyChanged
{
// 记录图标字体
public FontFamily FontFamily { get; set; }
// 图标的C#转义代码
public string Icon { get; set; }
// 标题
public string Label { get; set; }
// 导航页
public Type DestPage { get; set; }
// 用于左侧矩形的显示
private Visibility selected = Visibility.Collapsed;
public Visibility Selected
{
get { return selected; }
set
{
selected = value;
this.OnPropertyChanged("Selected");
}
}
// 双向绑定,用于更新矩形是否显示
public event PropertyChangedEventHandler PropertyChanged; public void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}

  

  主页面框架代码

<Page
x:Class="HamburgerDemo.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:HamburgerDemo"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"> <Page.Resources>
<!--菜单的数据模板-->
<DataTemplate x:Key="DataTemplate">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="48" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions> <Rectangle Fill="{ThemeResource SystemControlBackgroundAccentBrush}"
Visibility="{Binding Selected, Mode=TwoWay}"
HorizontalAlignment="Left" Width="5" Height="48" /> <FontIcon FontFamily="{Binding FontFamily}" Glyph="{Binding Icon}" Foreground="White"
VerticalAlignment="Center"
Margin="-2,0,0,0" Width="48" Height="48" /> <TextBlock Grid.Column="1"
Text="{Binding Label}" Foreground="White"
Margin="12,0,0,0" VerticalAlignment="Center" />
</Grid>
</DataTemplate>
<!--ListViewItem样式定制-->
<Style x:Key="NavMenuItemContainerStyle" TargetType="ListViewItem">
<Setter Property="MinWidth" Value="{StaticResource SplitViewCompactPaneThemeLength}"/>
<Setter Property="Height" Value="48"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="UseSystemFocusVisuals" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewItem">
<ListViewItemPresenter ContentTransitions="{TemplateBinding ContentTransitions}"
Control.IsTemplateFocusTarget="True"
SelectionCheckMarkVisualEnabled="False"
PointerOverBackground="{ThemeResource SystemControlHighlightListLowBrush}"
PointerOverForeground="{ThemeResource ListViewItemForegroundPointerOver}"
SelectedBackground="Transparent"
SelectedForeground="{ThemeResource SystemControlForegroundAccentBrush}"
SelectedPointerOverBackground="{ThemeResource SystemControlHighlightListLowBrush}"
PressedBackground="{ThemeResource SystemControlHighlightListMediumBrush}"
SelectedPressedBackground="{ThemeResource SystemControlHighlightListMediumBrush}"
DisabledOpacity="{ThemeResource ListViewItemDisabledThemeOpacity}"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
ContentMargin="{TemplateBinding Padding}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Page.Resources> <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<!--汉堡菜单开关-->
<Button Name="PaneOpenButton"
FontFamily="Segoe MDL2 Assets" Content="" Foreground="White"
Background="{Binding BackgroundColor}"
Width="48" Height="48"
VerticalAlignment="Top" Canvas.ZIndex="100" /> <SplitView Name="RootSplitView"
DisplayMode="CompactOverlay"
CompactPaneLength="48" OpenPaneLength="256"
IsPaneOpen="True"> <SplitView.Pane>
<Grid Background="#CC000000">
<Grid.RowDefinitions>
<!--空出Button的高度-->
<RowDefinition Height="48" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!--一级菜单-->
<ListView Name="NavMenuPrimaryListView"
Grid.Row="1" VerticalAlignment="Top"
SelectionMode="None" IsItemClickEnabled="True"
ItemTemplate="{StaticResource DataTemplate}"
ItemContainerStyle="{StaticResource NavMenuItemContainerStyle}"/>
<!--二级菜单-->
<ListView Name="NavMenuSecondaryListView"
Grid.Row="2" VerticalAlignment="Bottom"
SelectionMode="None" IsItemClickEnabled="True"
ItemTemplate="{StaticResource DataTemplate}"
ItemContainerStyle="{StaticResource NavMenuItemContainerStyle}"
BorderBrush="{ThemeResource SystemControlBackgroundAccentBrush}" BorderThickness="0,1,0,0" />
</Grid>
</SplitView.Pane> <SplitView.Content>
<Frame Name="RootFrame" />
</SplitView.Content> </SplitView> </Grid>
</Page>

  主页面的后台代码

using HamburgerDemo.Views;
using System.Collections.Generic;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Media; namespace HamburgerDemo
{
public sealed partial class MainPage : Page
{
// 为不同的菜单创建不同的List类型
private List<NavMenuItem> navMenuPrimaryItem = new List<NavMenuItem>(
new[]
{
new NavMenuItem()
{
FontFamily = new FontFamily("Segoe MDL2 Assets"),
Icon = "\xE10F",
Label = "页面1",
Selected = Visibility.Visible,
DestPage = typeof(Page1)
}, new NavMenuItem()
{
FontFamily = new FontFamily("Segoe MDL2 Assets"),
Icon = "\xE11A",
Label = "页面2",
Selected = Visibility.Collapsed,
DestPage = typeof(Page1)
}, new NavMenuItem()
{
FontFamily = new FontFamily("Segoe MDL2 Assets"),
Icon = "\xE121",
Label = "页面3",
Selected = Visibility.Collapsed,
DestPage = typeof(Page1)
}, new NavMenuItem()
{
FontFamily = new FontFamily("Segoe MDL2 Assets"),
Icon = "\xE122",
Label = "页面4",
Selected = Visibility.Collapsed,
DestPage = typeof(Page1)
} }); private List<NavMenuItem> navMenuSecondaryItem = new List<NavMenuItem>(
new[]
{
new NavMenuItem()
{
FontFamily = new FontFamily("Segoe MDL2 Assets"),
Icon = "\xE713",
Label = "设置",
Selected = Visibility.Collapsed,
DestPage = typeof(Page1)
}
}); public MainPage()
{
this.InitializeComponent();
// 绑定导航菜单
NavMenuPrimaryListView.ItemsSource = navMenuPrimaryItem;
NavMenuSecondaryListView.ItemsSource = navMenuSecondaryItem;
// SplitView 开关
PaneOpenButton.Click += (sender, args) =>
{
RootSplitView.IsPaneOpen = !RootSplitView.IsPaneOpen;
};
// 导航事件
NavMenuPrimaryListView.ItemClick += NavMenuListView_ItemClick;
NavMenuSecondaryListView.ItemClick += NavMenuListView_ItemClick;
// 默认页
RootFrame.SourcePageType = typeof(Page1);
} private void NavMenuListView_ItemClick(object sender, ItemClickEventArgs e)
{
// 遍历,将选中Rectangle隐藏
foreach (var np in navMenuPrimaryItem)
{
np.Selected = Visibility.Collapsed;
}
foreach (var ns in navMenuSecondaryItem)
{
ns.Selected = Visibility.Collapsed;
} NavMenuItem item = e.ClickedItem as NavMenuItem;
// Rectangle显示并导航
item.Selected = Visibility.Visible;
if (item.DestPage != null)
{
RootFrame.Navigate(item.DestPage);
} RootSplitView.IsPaneOpen = false;
}
}
}

  运行效果图如下

张高兴的 UWP 开发笔记:汉堡菜单进阶的更多相关文章

  1. 张高兴的 UWP 开发笔记:用 Thumb 控件仿制一个可拖动 Button

    在 WPF 上可用的控件拖动方法在 UWP 上大多没用,那干脆用 Thumb 仿制一个吧. 关于 Thumb 控件的教程也不多,毕竟在 WPF 控件拖动有很多种方法, Thumb 就显得很鸡肋了.下面 ...

  2. 张高兴的 UWP 开发笔记:横向 ListView

    ListView 默认的排列方向是纵向 ( Orientation="Vertical" ) ,但如果我们需要横向显示的 ListView 怎么办? Blend for Visua ...

  3. 张高兴的 UWP 开发笔记:应用内启动应用 (UWP Launch UWP)

    需求:在 A 应用内启动 B 应用,如果 B 应用未安装则跳转应用商店搜索. 启动方式使用 Uri 启动,本文使用尽可能简单,并且能拿来直接用的代码.不涉及启动后的应用数据交互,如需深入了解,请戳 M ...

  4. 张高兴的 UWP 开发笔记:手机状态栏 StatusBar

    UWP 有关应用标题栏 TitleBar 的文章比较多,但介绍 StatusBar 的却没几篇,在这里随便写写.状态栏 StatusBar 用法比较简单,花点心思稍微设计一下,对应用会是个很好的点缀. ...

  5. 张高兴的 UWP 开发笔记:定制 ContentDialog 样式

    我需要一个背景透明的 ContentDialog,像下图一样.如何定制?写了一个简单的示例(https://github.com/ZhangGaoxing/uwp-demo/tree/master/C ...

  6. 张高兴的 Xamarin.Forms 开发笔记:为 Android 与 iOS 引入 UWP 风格的汉堡菜单 ( MasterDetailPage )

    所谓 UWP 样式的汉堡菜单,我曾在"张高兴的 UWP 开发笔记:汉堡菜单进阶"里说过,也就是使用 Segoe MDL2 Assets 字体作为左侧 Icon,并且左侧使用填充颜色 ...

  7. UWP开发笔记——嵌套式页面的实现

    绪论 UWP开发中,Page是最常用的Control之一,通常情况下,在开发的application中,每一个页面就是一个Page.有时候,为了开发整合度更高,UI表现更为一致的UI,开发者需要把UI ...

  8. 安卓开发笔记——Menu菜单组件(选项菜单,上下文菜单,子菜单)

    菜单是用户界面中最常见的元素之一,使用非常频繁,在Android中,菜单被分为如下三种,选项菜单(OptionsMenu).上下文菜单(ContextMenu)和子菜单(SubMenu). 菜单的实现 ...

  9. uwp汉堡菜单的实现

    ---恢复内容开始--- 现在uwp上面的汉堡菜单(就是那个三道杠,点击之后会出现菜单)使用的越来越普遍,比如微软自己家的Cortana.现在我使用的实现方法是使用SplitView实现.首先Spli ...

随机推荐

  1. 记一次tomcat线程创建异常调优:unable to create new native thread

    测试在进行一次性能测试的时候发现并发300个请求时出现了下面的异常: HTTP Status 500 - Handler processing failed; nested exception is ...

  2. C语言 · 阶乘计算 · 基础练习

    问题描述 输入一个正整数n,输出n!的值. 其中n!=1*2*3*-*n. 算法描述 n!可能很大,而计算机能表示的整数范围有限,需要使用高精度计算的方法.使用一个数组A来表示一个大整数a,A[0]表 ...

  3. jsp中出现onclick函数提示Cannot return from outside a function or method

    在使用Myeclipse10部署完项目后,原先不出错的项目,会有红色的叉叉,JSP页面会提示onclick函数错误 Cannot return from outside a function or m ...

  4. PHP-解析验证码类--学习笔记

    1.开始 在 网上看到使用PHP写的ValidateCode生成验证码码类,感觉不错,特拿来分析学习一下. 2.类图 3.验证码类部分代码 3.1  定义变量 //随机因子 private $char ...

  5. 免费道路 bzoj 3624

    免费道路(1s 128MB)roads [输入样例] 5 7 21 3 04 5 13 2 05 3 14 3 01 2 14 2 1 [输出样例] 3 2 04 3 05 3 11 2 1 题解: ...

  6. java 设计模式

    目录: 设计模式六大原则(1):单一职责原则 设计模式六大原则(2):里氏替换原则 设计模式六大原则(3):依赖倒置原则 设计模式六大原则(4):接口隔离原则 设计模式六大原则(5):迪米特法则 设计 ...

  7. Flexible 弹性盒子模型之CSS flex-flow

    实例 让弹性盒的元素以相反的顺序显示,且在必要的时候进行拆行: display:flex; flex-flow:row-reverse wrap;   效果预览 浏览器支持 表格中的数字表示支持该属性 ...

  8. 烂泥:redis3.2.3安装与配置

    本文由ilanniweb提供友情赞助,首发于烂泥行天下 想要获得更多的文章,可以关注我的微信ilanniweb 前一段时间写过一篇codis集群的文章,写那篇文章主要是因为当时的项目不支持redis自 ...

  9. 第六代智能英特尔® 酷睿™ 处理器图形 API 开发人员指南

    欢迎查看第六代智能英特尔® 酷睿™ 处理器图形 API 开发人员指南,该处理器可为开发人员和最终用户提供领先的 CPU 和图形性能增强.各种新特性和功能以及显著提高的性能. 本指南旨在帮助软件开发人员 ...

  10. 《Note --- Unreal 4 --- Sample analyze --- StrategyGame(continue...)》

    ---------------------------------------------------------------------------------------------------- ...