在 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 的展开方向改为向下展开的更多相关文章

  1. 在 UWP 中实现 Expander 控件

    WPF 中的 Expander 控件在 Windows 10 SDK 中并不提供,本文主要说明,如何在 UWP 中创建这样一个控件.其效果如下图: 首先,分析该控件需要的一些特性,它应该至少包括如下三 ...

  2. UWP中新加的数据绑定方式x:Bind分析总结

    UWP中新加的数据绑定方式x:Bind分析总结 0x00 UWP中的x:Bind 由之前有过WPF开发经验,所以在学习UWP的时候直接省略了XAML.数据绑定等几个看着十分眼熟的主题.学习过程中倒是也 ...

  3. 飞流直下的精彩 -- 淘宝UWP中瀑布流列表的实现

    在淘宝UWP中,搜索结果列表是用户了解宝贝的重要一环,其中的图片效果对吸引用户点击搜索结果,查看宝贝详情有比较大的影响.为此手机淘宝特意在搜索结果列表上采用了2种表现方式:一种就是普通的列表模式,而另 ...

  4. [UWP小白日记-11]在UWP中使用Entity Framework Core(Entity Framework 7)操作SQLite数据库(一)

    前言 本文中,您将创建一个通用应用程序(UWP),使用Entity Framework Core(Entity Framework 7)框架在SQLite数据库上执行基本的数据访问. 准备: Enti ...

  5. [UWP-小白日记16]UWP中的3D变换API

    原文:[UWP-小白日记16]UWP中的3D变换API 还没开始 好久没写博客了,再来开坑. 正文 Transform3D:“这个和CSS的3D好像的说” PerspectiveTransform3D ...

  6. UWP中实现自定义标题栏

    UWP中实现自定义标题栏 0x00 起因 在UWP开发中,有时候我们希望实现自定义标题栏,例如在标题栏中加入搜索框.按钮之类的控件.搜了下资料居然在一个日文网站找到了一篇介绍这个主题的文章: http ...

  7. 淘宝UWP中的100个为什么

    从淘宝UWP第一版发布到现在,已经有十个月了,期间收到了用户各种各样的反馈,感谢这些用户的反馈,指导我们不断的修正.完善应用.但是也有一部分需求或建议,由于资源或技术的限制,目前确实无法做到,只能对广 ...

  8. 揭秘Windows10 UWP中的httpclient接口[2]

    阅读目录: 概述 如何选择 System.Net.Http Windows.Web.Http HTTP的常用功能 修改http头部 设置超时 使用身份验证凭据 使用客户端证书 cookie处理 概述 ...

  9. C# Word中设置/更改文本方向

    C# Word中设置/更改文本方向 一般情况下在Word中输入的文字都是横向的,今天给大家分享两种方法来设置/更改一个section内的所有文本的方向及部分文本的方向,有兴趣的朋友可以试下. 首先,从 ...

随机推荐

  1. Check out our list of adidas NMD Singapore retailers

    The adidas NMD Singapore is confirmed to produce on The month of january 14th at select adidas Origi ...

  2. Spring整合Mybatis 之分页插件使用

    [分页插件项目中的正式代码一共有个5个Java文件,这5个文件的说明如下] Page<E>[必须]:分页参数类,该类继承ArrayList,虽然分页查询返回的结果实际类型是Page< ...

  3. 11月26号host

    127.0.0.1 localhost255.255.255.255 broadcasthost::1 localhostfe80::1%lo0 localhost # Google start216 ...

  4. Python 安装pytz

    1.    https://pypi.org/project/pytz/#files 2.    下载上图标黄的文件, 3.    pip install 4.    from pytz import ...

  5. 反射获取成员方法(Method)

    1.1.1 反射公开的非静态的成员方法 Method getDeclaredMethod(String name,Class ... parameterTypes)获取某个方法. 说明: 1)在Cla ...

  6. 项目中使用protobuf 3.0

    protocol buffer从3.0 原生的compiler支持c++,Java,Python,Go,Ruby,JavaNano,JavaScript,Objective-C,C#,PHP这篇文章作 ...

  7. 20145118 《Java程序设计》 第2周学习总结

    20145118 <Java程序设计> 第2周学习总结 教材学习内容总结 起初翻开课本看到第三章的章节题目”基础语法”时,我就明白这是一章需要我们牢牢掌握并理解的学科.通过看课本我了解到, ...

  8. 更改idea快捷键方式为eclipse风格

    打开配置窗口 菜单栏中的File-settings 或者快捷键 ctrl+alt+s 设置keymap 在弹出的setting页面中左侧导航中选择Keymap: 在keymaps下拉列表中选择Ecli ...

  9. 一个简单的Python字符串处理文件

    #!/usr/bin/env python3 import re def lineprocess(line): res = '' index = 47 if line[index] == 'e': i ...

  10. 前端工程化 - Yeoman

    什么是Yeoman Yeoman是一个前端构建工具.它整合了yo(yeoman).gulp/grunt和npm/bower等工具,组成了一个完整的工具集合,为前端开发提供了一套完整的解决方案. Yeo ...