UWP 扩展/自定义标题栏的方法,一些概念和一些注意事项
原文 UWP 扩展/自定义标题栏的方法,一些概念和一些注意事项
在 Windows 10 的前几个版本中将页面内容扩展到标题栏上还算简单,主要是没什么坑。直到一些新控件的引入和一些外观设计趋势变化之后,扩展标题栏开始出现一些坑了。
本文将重温 UWP 自定义标题栏或者扩展标题栏的方法,但更重要的是解决一些坑。
扩展/自定义标题栏
要扩展标题栏,只需要拿到 CoreApplicationView 的实例,然后设置 TitleBar 的 ExtendViewIntoTitleBar 属性为 true 即可。
var applicationView = CoreApplication.GetCurrentView();
applicationView.TitleBar.ExtendViewIntoTitleBar = true;
要自定义标题栏,只需要拿到 ApplicationView 的实例,然后设置 TitleBar 里各种属性接口。
var titleBar = ApplicationView.GetForCurrentView().TitleBar;
titleBar.BackgroundColor = Colors.Khaki;
titleBar.ButtonBackgroundColor = Colors.Transparent;
一些概念
那么问题来了,为什么前者需要拿到 CoreApplicationView 的实例,后者需要拿到 ApplicationView 的实例?它们到底是什么区别?
我在 CoreApplication/Application、CoreWindow/Window 之间的区别 一文中提到过 CoreApplication、CoreWindow 和 CoreDispatcher 之间的关系。继续借用那篇文章中的图:

其中,Window 是对 CoreWindow 的封装,提供了更多与 XAML 相关的功能。这里的 ApplicationView 也是这样,是对 CoreApplication 的封装,提供了 XAML 相关的功能。
那篇文章中详细描述了这几个概念之间的关系和区别。考虑到阅读的一致性,我摘抄过来:
具体来说,
CoreWindow是与操作系统、与整个应用打交道的类型,提供了诸如窗口的尺寸、位置、输入状态等设置或调用;Window是与应用内 UI 打交道的类型,比如可以设置窗口内显示的 UI,设置内部哪个控件属于标题栏,获取此窗口内的Compositor。与之对应的,CoreApplicationView是应用与操作系统交互,与窗口消息循环机制协同工作的类型,包含窗口客户区和非客户区设置;ApplicationView也是与应用内 UI 打交道的类型,它可以使用 XAML 相关的类型对应用程序视图进行更方便的设置。总结起来,
CoreWindow和CoreApplicationView提供更加核心的操作系统或应用底层功能,而Window和ApplicationView对前者进行了封装,使得我们能够使用Windows.UI.Xaml命名空间下的类型对窗口和应用视图进行控制。
于是,我们便能够理解为什么扩展标题栏和设置标题栏颜色会使用到两个不一样的类型了。
ExtendViewIntoTitleBar 是改变了窗口的客户区(Client Area)和非客户区(Non-client Area)组成,这是传统 Win32 编程中的概念,是更接近操作系统底层的概念。BackgroundColor 和 ButtonBackgroundColor 这里需要用到 Windows.UI.Xaml 命名空间中的颜色,而 CoreApplicationView 太底层,无法使用 XAML 颜色。
一些坑
控件在标题栏区域无法交互
想必当你扩展到标题栏后,在标题栏区域增加一些按钮的时候,肯定会遇到下面的情况:

▲ 按钮在标题栏区域的一半无法交互
这显然是无法接受的。
然而,当我们将一个 XAML 控件指定为标题栏之后,就只会是那个控件所在的区域响应标题栏操作,其他地方就会恢复正常。
// TitleBar 是我在 XAML 中写的一个 x:Name="TitleBar" 的控件。
Window.Current.SetTitleBar(TitleBar);

▲ 按钮在标题栏区域现在可以交互了
特别说明一下,SetTitleBar 传入的是 UIElement 类型的实例,也就是说这也是 XAML 交互的一部分。我们需要使用 Window 的实例,而不是 CoreWindow 的实例。
更高的标题栏,或者被遮挡
如果被指定为标题栏的控件更大,超出标题栏区域了,它还会成为标题栏吗?如果被其他控件遮挡了,它还会响应标题栏事件吗?
实际看来,无论它多大,都能响应标题栏事件;但被遮挡的部分就真的被遮挡了,没有标题栏响应。

▲ 更高的标题栏,或者被遮挡
事实上,指定为标题栏的控件可以在界面的任何地方,不需要一定在顶部。只不过,绝大多数不作死的应用都不会这样设置吧!
在什么时机调用?
扩展标题栏用的是 CoreApplicationView,自定义标题栏颜色用的是 ApplicationView,将控件指定为标题栏用的是 Window。如果我们的应用只有一个视图,其实我们随便找一个初始化的地方调用就好了。但如果我们的应用有多个视图,那么给非主要视图调用的时候就需要在其初始化之后了。阅读 理解 UWP 视图的概念,让 UWP 应用显示多个窗口(多视图) 了解如何编写多个视图的 UWP 应用,了解非主要视图的初始化时机。
当然,如果你比较极客,从 Main 函数开始写 UWP 应用,就像我在 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序 一文中做的一样,那么你也需要等到初始化完毕之后才能调用(至少是 SetWindow 之后了)。
适配移动设备
移动设备上并不是标题栏,而是状态了和虚拟按键。关于扩展视图到这些区域,可以阅读 win10 uwp 标题栏 - 林德熙。
参考资料
本文会经常更新,请阅读原文: https://walterlv.com/post/tips-for-customize-uwp-title-bar.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。
UWP 扩展/自定义标题栏的方法,一些概念和一些注意事项的更多相关文章
- List<T>直接充当Combox控件DataSource并扩展自定义记录的方法
一般认为List只有转换为DataTable后才能充当CombBox的数据源,其实不然: List<SYS_COMMANDS> comdList = _menuMan.Load(c =&g ...
- CI框架扩展自定义控制器的方法
扩展CI中的控制器 有时需要对CI中的控制器作统一操作,如进行登录和权限验证,这时就可以通过扩展CI控制器来实现. 扩展CI控制器只需要在application/core文件夹中建一个继承自CI_Co ...
- UWP中实现自定义标题栏
UWP中实现自定义标题栏 0x00 起因 在UWP开发中,有时候我们希望实现自定义标题栏,例如在标题栏中加入搜索框.按钮之类的控件.搜了下资料居然在一个日文网站找到了一篇介绍这个主题的文章: http ...
- 双击CAD对象(具有扩展数据),显示自定义对话框实现方法
转自:Cad人生 链接:http://www.cnblogs.com/cadlife/p/3463337.html 题目:双击CAD对象,显示自定义对话框实现方法 内容粘贴如下: 主要是绑定两个事件: ...
- 【Win10开发】自定义标题栏
UWP 现在已经可以自定义标题栏了,毕竟看灰色时间长了也会厌烦,开发者们还是希望能够将自己的UI做的更加漂亮,更加与众不同.那么废话不多说,我们开始吧! 首先要了解ApplicationViewTit ...
- [置顶]
xamarin android自定义标题栏(自定义属性、回调事件)
自定义控件的基本要求 这篇文章就当是自定义控件入门,看了几篇android关于自定义控件的文章,了解了一下,android自定义控件主要有3种方式: 自绘控件:继承View类,所展示的内容在OnDra ...
- 基于electron+vue+element构建项目模板之【自定义标题栏&右键菜单项篇】
1.概述 开发平台OS:windows 开发平台IDE:vs code 本篇章将介绍自定义标题栏和右键菜单项,基于electron现有版本安全性的建议,此次的改造中主进程和渲染进程彼此语境隔离,通过预 ...
- WPF 自定义标题栏 自定义菜单栏
自定义标题栏 自定义列表,可以直接修改WPF中的ListBox模板,也用这样类似的效果.但是ListBox是不能设置默认选中状态的. 而我们需要一些复杂的UI效果,还是直接自定义控件来的快 GitHu ...
- Android开发-取消程序标题栏或自定义标题栏
注:本文由Colin撰写,版权所有!转载请注明原文地址,谢谢合作! 在Android开发中,跟据需要我们有时候需要自定义应用程序的标题栏或者取消程序的标题栏,下面本菜鸟在此记录与分享一下自己使用的方法 ...
随机推荐
- 如何使stm32程序更好移植, 结构体相当于define
原创:转载请标注引用地址 如何定义 led1对应于PA8 呢 :对于我一开始学习的方法:: #include "main.h" #define led1 GPIO_Pi ...
- [Tools] Fix Only Committed Files with Prettier and lint-staged
In this lesson we'll use prettier and lint-staged to run prettier only on files that have been chang ...
- 数学之路-python计算实战(7)-机器视觉-图像产生加性零均值高斯噪声
图像产生加性零均值高斯噪声.在灰度图上加上噪声,加上噪声的方式是每一个点的灰度值加上一个噪声值.噪声值的产生方式为Box-Muller算法生成高斯噪声. 在计算机模拟中,常常须要生成正态分布的数值.最 ...
- css聊天气泡样式
https://files.cnblogs.com/files/zonglonglong/%E8%81%8A%E5%A4%A9%E6%B0%94%E6%B3%A1.zip
- 监听text等的改变事件
oninput事件是html5的标准事件,支持ie9和以上以及其他的火狐啊谷歌啊等浏览器 ie9以下的可以用onpropertychange <head> <script t ...
- chrome-vimium在markdown插件的页面失去效果
chrome-vimium在markdown插件的页面失去效果
- ITFriend创业阶段的服务器环境搭建手册
创业阶段,进一步实践了Linux环境搭建和维护,下面是一些常用软件的搭建步骤和参考资料,仅供自己和诸位参考. 我个人还是比较倾向"一站式Web开发"的,自己想做点事,需要太多的技能 ...
- uboot中rtc顶层分析
uboot一般不会要求开启rtc,只是还是支持rtc以备特殊需求的. 底层驱动移植前面两篇已经介绍.这里介绍顶层的调用过程.顶层在uboot/common/cmd_date.c /* * (C) Co ...
- Ambari——大数据平台的搭建利器(一)
Ambari 跟 Hadoop 等开源软件一样,也是 Apache Software Foundation 中的一个项目,并且是**项目.目前最新的发布版本是 2.0.1,未来不久将发布 2.1 版本 ...
- ITFriend创业败局(三):技术人员创业,需要尽可能避免,或者需要解决的5个重要问题
一.插科打诨: 本想给小雷粉,做一个创业"成功案例"的,结果做成了一个"反面教材"~ No zuo,no die~ 二.写作目的:分享自己作为一名技术人员,或者 ...