将 UWP 中 CommandBar 的展开方向改为向下展开
在 UWP 中使用 CommandBar 来迅速添加一组功能按钮是非常迅速的,是 UWP 中推荐的交互方案之一。也许你能见到 CommandBar 按你所需向下展开,不过可能更多数情况会看到 CommandBar 的展开方向是向上的。
本文将解释 CommandBar 的展开方向逻辑,并且提供多种方法来解决它展开方向的问题。
本文内容
为什么我们需要更改 CommandBar 的展开方向?
<CommandBar Background="#40000000" ClosedDisplayMode="Compact">
<AppBarButton Icon="Add" Label="添加" ToolTipService.ToolTip="添加一个 RSS 订阅" />
<AppBarButton Icon="Bullets" Label="编辑" ToolTipService.ToolTip="进入编辑状态" />
</CommandBar>
看下图的例子,我们有一个在顶部的 CommandBar,但是它展开的时候方向是向上的,以至于挡住了顶部的标题栏。

▲ CommandBar 在不合适的方向展开
理论上标题栏是挡不住的。不过,由于流畅设计(Fluent Design)的存在,越来越多的应用开始使用自定义的标题栏,以获得浑然天成的流畅设计效果。而上图就是其中的一个例子。
我们当然希望在顶部的 CommandBar 其展开方向是向下,所以我们需要找到一些方法。
将 CommandBar 改为向下展开的几种方法
首先定一个基调:CommandBar 的默认展开方向就是向上,无论你使用哪种方式,本质上都没有解决其展开方向的问题。
所以以下方法都有可能在你的使用场景下失效,除了大杀器 —— 重写 Template。
方法一:使用 Page.TopAppBar 属性
<Page x:Class="Walterlv.Rssman.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Page.TopAppBar>
<CommandBar Background="#40000000" ClosedDisplayMode="Compact">
<AppBarButton Icon="Add" Label="添加" ToolTipService.ToolTip="添加一个 RSS 订阅" />
<AppBarButton Icon="Bullets" Label="编辑" ToolTipService.ToolTip="进入编辑状态" />
</CommandBar>
</Page.TopAppBar>
<Grid>
</Grid>
</Page>
如果你并没有做一些奇怪的样式,是一个 Demo 或者是刚开始做的应用,那么此方法应该对你有效。

▲ Page.TopAppBar 中的 CommandBar
看!现在 CommandBar 向下展开了。这就是我们的解决方案之一。
不过,觉得怪怪的是不是?因为我自定义了标题栏,当然不能让标题栏挡住我的控件啊!
千万不要尝试将你的 Page 设置一个 Margin 让他下移,因为:

▲ 无论你设置到哪个 Page 中,无论 Margin 设为多少,就算是给 Frame 外面的 Grid 设置 Margin,通通都是无效的!Page.TopAppBar 在应用窗口级别的。
正如官网中所描述的那样:
Command bars can be placed at the top of the app window, at the bottom of the app window, and inline.
方法二:更改布局,使得顶部空间不足以展开 CommandBar
CommandBar 的 ClosedDisplayMode 设为 Compact 时,折叠状态高度 48,展开状态高度 60;在设为 Minimal 时,折叠状态高度 24,展开状态依然是 60。

▲ 各种模式下的展开和折叠高度
鉴于 CommandBar 仅在空间不足时才会从向上展开变为向下展开,所以我们可以利用顶部空间的距离差来完成方向的修改。
对于 Compact 模式,我们仅能在上方预留不足 12 的尺寸,而对于 Minimal 模式,我们则有不大于 36 的尺寸可以预留。
在我们一开始的例子中,我们需要留出标题栏的高度,而标题栏高度为 32,所以使用 Minimal 模式时,我们的展开方向自然因为顶部空间不足而向下展开。另外,12 像素除了留白以外也没什么作用,所以实质上 Compact 模式并不能通过这种方式解决展开方向的问题。

▲ 在使用 Minimal 的关闭模式时,可以向下展开
如果你设置的 SecondaryCommand 比较长,那么展开的时候也会占用较多的控件,于是也可以强制 CommandBar 向下展开。
方法三:设置 DefaultLabelPosition 避开展开方向的问题
如果不容易改展开方向,那么不让 CommandBar 面临展开方向的问题也是一个不错的解决方案 —— 为 CommandBar 设置 DefaultLabelPosition 便是这样的方案。
将 DefaultLabelPosition 属性设置为 Right 或者 Collapsed 而不是 Bottom,那么 CommandBar 便不再需要展开这些按钮了,因为即便展开也不会显示更多的信息了,除了那个根本不会影响高度的更多项。

▲ 设置为 Collapsed 或者 Right 的 DefaultLabelPosition
方法四:修改 CommandBar 的模板
不得不说这真是一个令人难受的方法,因为定义 CommandBar 模板和样式的代码行数有 1400 行左右。但这也是目前依然使用 CommandBar 控件时最好的方案了。

▲ 编辑控件模板的副本
现在,使用 Visual Studio 设计器来帮助我们获得 CommandBar 的完整默认样式定义,就像上图那样。于是,我们可以阅读其代码并修改展开方向了。
代码很长,为了能够迅速理解其结构,我将其最关键的大纲部分贴到下面:
<ControlTemplate x:Key="CommandBarTemplate1">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="DisplayModeStates">
<VisualStateGroup.Transitions>
<VisualState From="CompactClosed" To="CompactOpenUp" />
<VisualState From="CompactOpenUp" To="CompactClosed" />
<VisualState From="CompactClosed" To="CompactOpenDown" />
<VisualState From="CompactOpenDown" To="CompactClosed" />
<VisualState From="MinimalClosed" To="MinimalOpenUp" />
<VisualState From="MinimalOpenUp" To="MinimalClosed" />
<VisualState From="MinimalClosed" To="MinimalOpenDown" />
<VisualState From="MinimalOpenDown" To="MinimalClosed" />
<VisualState From="HiddenClosed" To="HiddenOpenUp" />
<VisualState From="HiddenOpenUp" To="HiddenClosed" />
<VisualState From="HiddenClosed" To="HiddenOpenDown" />
<VisualState From="HiddenOpenDown" To="HiddenClosed" />
</VisualStateGroup.Transitions>
<VisualState x:Name="CompactClosed" />
<VisualState x:Name="CompactOpenUp" />
<VisualState x:Name="CompactOpenDown" />
<VisualState x:Name="MinimalClosed" />
<VisualState x:Name="MinimalOpenUp" />
<VisualState x:Name="MinimalOpenDown" />
<VisualState x:Name="HiddenClosed" />
<VisualState x:Name="HiddenOpenUp" />
<VisualState x:Name="HiddenOpenDown" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
可以看到,对于每一种 ClosedDisplayMode,都有三种状态与之对应 —— Closed、Up 和 Down。当然,Up 就是向上展开时的状态,Down 就是向下展开时的状态。而 Closed、Up 和 Down 之间的状态切换有四种 —— Closed 到 Up、Up 到 Closed、Closed 到 Down 以及 Down 到 Closed。
于是,我们要获得任何时候都向下展开的能力,我们便需要将所有的 Up 状态修改成 Down 的状态。
现在,我们将 将 <VisualState From="CompactClosed" To="CompactOpenDown" /> 的代码复制到 <VisualState From="CompactClosed" To="CompactOpenUp" /> 中,<VisualState From="CompactOpenDown" To="CompactClosed" /> 内部的代码复制到 <VisualState From="CompactOpenUp" To="CompactClosed" /> 中,将 <VisualState x:Name="CompactOpenDown" /> 内的代码复制到 <VisualState x:Name="CompactOpenUp" /> 中。
也就是说,我们将所有 CompactClosed 和 CompactDown 的状态复制到了 CompactClosed 和 CompactUp 的状态中。这样,即便 CommandBar 判定为向上展开,实际上的动画和交互也都是向下展开的了。
以下是这样修改后的效果。

▲ 使用样式更改的展开方向
究竟应该如何修改 CommandBar 的展开方向
在多数情况下,我想我们并没有特别强烈的需求一定要让 CommandBar 在顶部依然有空间的情况下展开方向向下。
如果有,那通常也是中大型项目,这时 CommandBar 样式和模板所占用的那 1400 行左右的代码也就不显得多了。
但对于小型个人项目而言,可以考虑修改应用程序的外观设计来规避这么长的代码。例如让 CommandBar 始终显示或隐藏文字,或者让 CommandBar 默认为 Minimal 的状态。
如果你对其他控件有小型样式的修改需求,可以阅读我的另一篇文章:UWP 轻量级样式定义(Lightweight Styling)。
将 UWP 中 CommandBar 的展开方向改为向下展开的更多相关文章
- 在 UWP 中实现 Expander 控件
WPF 中的 Expander 控件在 Windows 10 SDK 中并不提供,本文主要说明,如何在 UWP 中创建这样一个控件.其效果如下图: 首先,分析该控件需要的一些特性,它应该至少包括如下三 ...
- UWP中新加的数据绑定方式x:Bind分析总结
UWP中新加的数据绑定方式x:Bind分析总结 0x00 UWP中的x:Bind 由之前有过WPF开发经验,所以在学习UWP的时候直接省略了XAML.数据绑定等几个看着十分眼熟的主题.学习过程中倒是也 ...
- 飞流直下的精彩 -- 淘宝UWP中瀑布流列表的实现
在淘宝UWP中,搜索结果列表是用户了解宝贝的重要一环,其中的图片效果对吸引用户点击搜索结果,查看宝贝详情有比较大的影响.为此手机淘宝特意在搜索结果列表上采用了2种表现方式:一种就是普通的列表模式,而另 ...
- [UWP小白日记-11]在UWP中使用Entity Framework Core(Entity Framework 7)操作SQLite数据库(一)
前言 本文中,您将创建一个通用应用程序(UWP),使用Entity Framework Core(Entity Framework 7)框架在SQLite数据库上执行基本的数据访问. 准备: Enti ...
- [UWP-小白日记16]UWP中的3D变换API
原文:[UWP-小白日记16]UWP中的3D变换API 还没开始 好久没写博客了,再来开坑. 正文 Transform3D:“这个和CSS的3D好像的说” PerspectiveTransform3D ...
- UWP中实现自定义标题栏
UWP中实现自定义标题栏 0x00 起因 在UWP开发中,有时候我们希望实现自定义标题栏,例如在标题栏中加入搜索框.按钮之类的控件.搜了下资料居然在一个日文网站找到了一篇介绍这个主题的文章: http ...
- 淘宝UWP中的100个为什么
从淘宝UWP第一版发布到现在,已经有十个月了,期间收到了用户各种各样的反馈,感谢这些用户的反馈,指导我们不断的修正.完善应用.但是也有一部分需求或建议,由于资源或技术的限制,目前确实无法做到,只能对广 ...
- 揭秘Windows10 UWP中的httpclient接口[2]
阅读目录: 概述 如何选择 System.Net.Http Windows.Web.Http HTTP的常用功能 修改http头部 设置超时 使用身份验证凭据 使用客户端证书 cookie处理 概述 ...
- C# Word中设置/更改文本方向
C# Word中设置/更改文本方向 一般情况下在Word中输入的文字都是横向的,今天给大家分享两种方法来设置/更改一个section内的所有文本的方向及部分文本的方向,有兴趣的朋友可以试下. 首先,从 ...
随机推荐
- tornado 入门
Overview FriendFeed是一款使用 Python 编写的,相对简单的 非阻塞式 Web 服务器.其应用程序使用的 Web 框架看起来有些像 web.py 或者 Google 的 weba ...
- idea中使用插件Grep Console在IDEA的log的不同的级别,可以设置不同的颜色。
一.安装. 1. 2. 3. 二,使用. 1. 2.
- WebCollector2.7爬虫框架——在Eclipse项目中配置
WebCollector2.7爬虫框架——在Eclipse项目中配置 在Eclipse项目中使用WebCollector爬虫非常简单,不需要任何其他的配置,只需要导入相关的jar包即可. Netbea ...
- python2.7无法安装python-ldap、django-auth-ldap
1.安装报错信息: error: Microsoft Visual C++ 9.0 is required. Get it from http://aka.ms/vcpython27 或者fatal ...
- 20145303 刘俊谦《网络对抗》shellcode注入&Return-to-libc攻击深入
20145303 刘俊谦<网络对抗>shellcode注入&Return-to-libc攻击深入 Shellcode注入 shellcode实际是一段代码,但却作为数据发送给受攻击 ...
- 20145314郑凯杰《网络对抗技术》实验5 MSF基础应用
20145314郑凯杰<网络对抗技术>实验5 MSF基础应用 1.0 MS08_067安全漏洞 1.1 实验目标 了解掌握metasploit平台的一些基本操作,能学会利用已知信息完成简单 ...
- linux内核分析第三周-跟踪分析Linux内核的启动过程
一.实验流程 1.打开环境 执行命令:cd LinuxKernel/ 执行命令:qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd root ...
- 常用<meta>
转自:http://segmentfault.com/a/1190000002407912 w3c -- <meta>标签:http://www.w3school.com.cn/tags/ ...
- hdu 6301 Distinct Values(贪心)题解
题意:长为n的串,给你m个区间,这些区间内元素不重复,问这样的串字典序最小为? 思路:用set保存当前能插入的元素,这样就能直接插入最小元素了.对操作按l排序,因为排过的不用排,所以两个指针L,R是一 ...
- Jwt访问api提示401错误 Authorization has been denied for this request
教程 http://bitoftech.net/2015/02/16/implement-oauth-json-web-tokens-authentication-in-asp-net-web-ap ...