2021年6月24日,Windows 11 正式對外發布,對於UWP開發者來說,這一天同樣值得紀念,因為WinUI 2.6也正式釋出了!
相同的時間點意味著一件事,即WinUI 2.6和Windows 11緊密相關,事實上,在微軟內部,我們的應用乃至於部分系統元件,都依賴於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渲染的一種半透明材質。但它具備以下特點:
- 僅用於應用背景。
- 僅支援對牆紙虛化。作為比較,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的顏色
在新的設計語言中,視覺層可以大致分為三個層級:
- BaseLayer,對應著底層的Mica。
- SurfaceLayer,對應頁面的底色,即作為Frame承載的顏色。
- ContentLayer,對應內容底色,比如卡片式設計中的卡片底色。
這種Layer的資源在Common_themeresources_any.xaml中,你能找到諸如“LayerFillColorDefaultBrush”或者“CardBackgroundFillColorDefault”等資源,在適合的場景中引用它們吧,你能夠為此建立新的沉浸式體驗。
關於新版WinUI的介紹,大致就是這樣,微軟這回在UI上花費的氣力很大,大家可以保持期待。
當然了,你知道的,微軟的工作挺緊張的,壓力也挺大,我也需要做點個人專案來放鬆放鬆,猜猜這是什麼(全部基於WinUI 2.6)?
最後,歡迎使用WinUI 2.6!