[UWP] WinUI 2.6 使用指南

2021年6月24日,Windows 11 正式对外发布,对于UWP开发者来说,这一天同样值得纪念,因为WinUI 2.6也正式发布了!

相同的时间点意味着一件事,即WinUI 2.6和Windows 11紧密相关,事实上,在微软,绝大部分UWP应用乃至于部分系统组件,都依赖于WinUI,也就是名为Microsoft.UI.Xaml的nuget包。

这也意味着,如果你想创建符合Windows 11设计语言的UWP应用,那么WinUI 2.6可能是个必选包。

我已经使用了一段时间的2.6版本,这篇文章就是根据我的使用经验总结的一篇引导,希望能带你快速入门WinUI 2.6,直接原地起飞。

安装

要在项目中安装WinUI 2.6,你需要确保你的项目最低系统版本符合WinUI 2.x的要求,即在15063以上,这里推荐将最低版本设置在17763(1809)及以上,该版本的UWP API已趋于稳定,且为大多数控件提供圆角(CornerRadius)支持。

然后打开nuget包管理器,搜索"Microsoft.UI.Xaml",选择版本为2.6.0(默认选中最新版),点击安装即可。

安装后会自动打开一个ReadMe文档,参照其中步骤将XamlControlsResources添加到App.xaml即可。

2.6nuget.png

材质

WinUI 2.6引入了新的材质,即Mica。和Acrylic材质类似,它也是通过Composition API渲染的一种半透明材质。但它具备以下特点:

  1. 目前仅能在Win11中看到明显效果
  2. 仅用于应用背景。
  3. 仅支持对墙纸虚化。作为比较,Acrylic可以对背景虚化,也可以对下层虚化。换句话说,当两个应用重叠时,你可以透过Acrylic看到下层的应用,而透过Mica,你可以也只能看到墙纸。
  4. 当前的Mica不能作为颜色资源在项目中引用,同时也不支持自定义透明度、颜色等。

这意味着,Mica的颜色将会极大地受到墙纸的影响。从某个角度来看,它能增加沉浸感。但从另外一个角度,它将为设计带来不确定因素,如果你的应用对各种组件的颜色有很大的限制,那么使用Mica可能会带来一些潜在的颜色冲突。

简单地介绍了一下Mica材质,现在让我们来看看怎么在项目中使用它吧。

让背景“透明”

前面提到过,Mica目前不能作为一种颜色资源被引用,那么当我们想使用Mica作为我们应用的背景色时,需要在我们的根元素上设置一个附加属性:

<!-- xmlns:muxc="using:Microsoft.UI.Xaml.Controls" -->

muxc:BackdropMaterial.ApplyToRootOrPageBackground="True"

这里的根元素可以是你的Page,或者是Page里的根控件。但要注意,该附加属性适用于Control类型,所以你不能在Grid这种Panel类型上添加该附加属性。

需要注意的是,当你为该控件设置了这个附加属性后,你不应再给这个控件设置Background。

你可以这样理解:

Mica将作为最底层的背景,它一直存在,所有的控件的视觉层都是在该背景层的基础上不断叠加。而我们显式设置BackdropMaterial.ApplyToRootOrPageBackground这个附加属性,意味着我们告诉应用:让底层的Mica露出来。

所以此时给控件设置Background就会和这个附加属性产生冲突,再扩展一下,不难想到,如果你给某个控件设置了这个附加属性,那么为了能让它工作,你就必须要让该控件下层的所有控件都不具备背景色,这样才能最底层的Mica”透“出来。而这也是Mica材质仅适合作为应用背景色的原因。

半透明是沉浸的基础

如果你理解了Mica的显示方式,那么接下来WinUI 2.6关于颜色资源的修改想必你也可以理解了。

我们可以把底部的Mica看作是一层滤光膜,背景的颜色透过这层膜隐约显现,墙纸改变时,应用的显示效果也随之改变,这就是新设计的一个特点:沉浸感。

为了能维持这种沉浸感,在WinUI 2.6中涉及到Layer的颜色资源基本都使用了半透明颜色,比如页面背景,卡片背景等,如果你决定要自定义颜色资源,请将这一点也考虑在设计之中,优先使用半透明的背景色,以维持整体的沉浸体验。

圆角

设计是一个循环,当我们看腻了自Win8以来的锐利直角后,在Win11我们又回归了平滑的圆角。

圆角设计在Win11中随处可见,而在WinUI 2.6中,几乎每一个控件都用上了圆角(甚至包括阴影!)。

为了维持整体的一致,WinUI 2.6定义了圆角的标准值:

资源名
ControlCornerRadius 4
OverlayCornerRadius 8

这两个值的使用贯穿始终,它们针对的目标控件也很明确。ControlCornerRadius常被用于交互型的控件,比如Button, TextBox等。OverlayCornerRadius常用于面板型的控件,比如Flyout, NavigationView等。

当我们在构建自己的控件时,应当参考上面的值,以构建完整的体验。

顺带一提,诸如Margin, Padding, CornerRadius这类布局属性,最好都设置为4的倍数,这样便于在各种缩放下都保持一个锐利的边缘,FontSize不在此列。

资源

这里将谈到WinUI库提供的一大助力,即其中定义的大量资源,而想使用它们,目前是有一定门槛的。

当我们引入WinUI包的时候,我们引入了什么?

当然,它包含大量的控件,以及对原生控件的样式重写,但这些并不足以支撑我们做出一个完整的,整体UI和谐的原生UWP应用(如果你打算采用新Windows的设计语言的话)。

我们总是需要创建自定义控件的,而如何保证我们创建出的自定义控件在样式风格上和WinUI一致呢?

这需要我们引用WinUI中定义的资源。

当我们创建的控件使用相同的布局参数,相同的背景,相近的设计思路,那么即便最终做出了个四不像,那也是WinUI风格的四不像。

这些资源都放在WinUI的Github仓库中,对原生控件的样式覆写在这个文件夹里:CommonStyles

而如果你需要WinUI定义的颜色资源,可以在这里找到:Common_themeresources_any.xaml

如果你需要圆角参数,可以在这里查看:CornerRadius_themeresources.xaml

WinUI仓库会是你在写基于WinUI2.6的UWP应用时最长逛的地方之一,碰到什么非预期的行为不要慌,看看源码即可,我们来举个例子:

如果你之前基于NavigationView创建了一个标准的UWP页面,在更新WinUI 2.6之后,你可能会发现NavigationView.Header部分多出来一部分边距。

navPadding.png

这些边距无法通过设置属性来修改,改HeaderTemplate也没用。这个时候要么就不要默认的Header,自己在NavigationView.Content定义一个Header控件;要么就查查为什么会这样。

通过在WinUI仓库中查找到对应的NavigationView文件夹(在dev文件夹里,很好找),然后查看NavigationView.xaml,我们会注意到在666行,它引用了一个名为“NavigationViewTitleHeaderContentControlTextStyle”的样式。

<ContentControl
    x:Name="HeaderContent"
    Grid.Row="1"
    Grid.Column="1"
    MinHeight="{StaticResource PaneToggleButtonHeight}"
    IsTabStop="False"
    Content="{TemplateBinding Header}"
    ContentTemplate="{TemplateBinding HeaderTemplate}"
    VerticalContentAlignment="Stretch"
    HorizontalContentAlignment="Stretch"
    Style="{StaticResource NavigationViewTitleHeaderContentControlTextStyle}"/>

用Github搜索它,找到原始定义,这时候我们会发现在内部这个Margin被写死了,所引用的资源是

NavigationViewHeaderMargin

<Style x:Key="NavigationViewTitleHeaderContentControlTextStyle" TargetType="ContentControl">
    <Setter Property="FontWeight" Value="SemiBold" />
    <Setter Property="FontSize" Value="28" />
    <Setter Property="FontFamily" Value="XamlAutoFontFamily" />
    <Setter Property="Margin" Value="{ThemeResource NavigationViewHeaderMargin}"/>
    <Setter Property="VerticalAlignment" Value="Stretch"/>
</Style>

它的定义如下:

<Thickness x:Key="NavigationViewHeaderMargin">56,44,0,0</Thickness>

我们要做的就比较明确了,在我们自己的项目中定义一个同名资源(可以放在App.xaml中),设置成自己想要的值,这样就实现了资源覆盖。

这是我们自定义WinUI控件的一个首选方式。而复制整份控件样式代码粘贴到自己项目里再做改动……不到万不得已,并不推荐。

使用预设资源

当我们引用WinUI中预设的资源时,它的确可以被引用,但没有Visual Studio的智能感知,我总是要到原始仓库去找对应的资源,也许以后可能会想个办法来解决它。

新版WinUI的资源命名有迹可循,重写原生控件时,通常是“控件名+DefaultStyle”,比如按钮的样式就是“ButtonDefaultStyle”,在查找通用资源字典(里面包含着公共资源)时,它们有不同的后缀,什么都没有的是最新的,后缀是"rs1"的表示旧版的资源。这里需要注意的是,有些资源定义如果是从旧版沿袭过来的,则依然会放在旧资源字典中,新的样式会引用它们。

来举两个例子:

AccentColor的变化

UWP应用通常会引用AccentColor这个系统资源来响应系统主题色的变化,而在WinUI中,如果你检查过,你会发现它所显示的AccentColor和我们设置的主题色不太一致,WinUI的要更亮一些。

这是因为WinUI所引用的主题色资源叫:AccentFillColorDefaultBrush

而它对应的Color是SystemAccentColorLight2,它已经存在于系统中,是主题色的亮化版本。

这样微小但明显的变化在新的WinUI中并不少见,所以在自己的项目中,尝试引用AccentFillColorDefaultBrush来替代以前的AccentColor吧。

Layer的颜色

官方文档中,按照不同的模式说明了应用分层。
在此基础上,我将可视层大致分作三层:

  • MicaLayer,对应着底层的Mica。
  • BaseLayer,对应页面的底色,即作为Frame承载的颜色。
  • ContentLayer,对应内容底色,比如卡片式设计中的卡片底色。

这种Layer的资源在Common_themeresources_any.xaml中,你能找到诸如“LayerFillColorDefaultBrush”或者“CardBackgroundFillColorDefault”等资源,在适合的场景中引用它们吧,你能够为此创建新的沉浸式体验。


关于新版WinUI的介绍,大致就是这样,微软这回在UI上花费的气力很大,大家可以保持期待。

当然了,你知道的,微软的工作挺紧张的,压力也挺大(手动滑稽),我也需要做点个人项目来放松放松,猜猜这是什么(全部基于WinUI 2.6)

bili.png

最后,欢迎使用WinUI 2.6!

posted @ 2021-06-25 17:41  云之幻  阅读(4915)  评论(4编辑  收藏  举报