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即可。
材質
WinUI 2.6引入了新的材質,即Mica。和Acrylic材質類似,它也是通過Composition API渲染的一種半透明材質。但它具備以下特點:
- 目前僅能在Win11中看到明顯效果
- 僅用於應用背景。
- 僅支持對牆紙虛化。作為比較,Acrylic可以對背景虛化,也可以對下層虛化。換句話說,當兩個應用重疊時,你可以透過Acrylic看到下層的應用,而透過Mica,你可以也只能看到牆紙。
- 當前的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的邊距
如果你之前基於NavigationView創建了一個標准的UWP頁面,在更新WinUI 2.6之后,你可能會發現NavigationView.Header部分多出來一部分邊距。
這些邊距無法通過設置屬性來修改,改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)
最后,歡迎使用WinUI 2.6!