針對UWP套用Mica與 WinUI 2
本文說明如何使用 WinUI 2,將 Mica 套用為 UWP app 的基底層,將應用程式和可見度設定在標題列區域中的優先順序。 如需使用 Mica 進行應用程式分層的詳細資訊,請參閱 Mica 材質。
雲母是一種不透明的材質,融合了使用者的佈景主題和桌面桌布,建立出高度個人化的外觀。 當使用者在畫面上移動視窗時,Mica 材質會動態調整,以使用應用程式下方的桌布來建立豐富的視覺效果。 此外,當應用程式處於非使用中狀態時,材質可協助使用者專注於目前的工作。
Mica 適用於在 Windows 11 版本 22000 或更新版本上執行時使用 WinUI 2 的 UWP app。 在 Windows 10 上,背景會回復為純色。
- WinUI 2 NuGet 套件(請參閱 開始使用 WinUI 2)
- 熟悉Mica材料。
- 熟悉標題列自定義
重要 API: BackdropMaterial 類別
若要在 UWP 應用程式中套用 Mica,請使用 WinUI 2 中的 BackdropMaterial 類別。 建議您在 XAML 內容的根元素上設定 GroundMaterial.ApplyToRootOrPageBackground 附加屬性,因為它會套用至整個內容區域(例如 Window)。 如果您的 app 有瀏覽 多個頁面的 Frame ,您應該在 Frame 上設定此屬性。 否則,您應該在應用程式的主要 頁面上 設定此屬性。
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
<Page muxc:BackdropMaterial.ApplyToRootOrPageBackground="True">
<TextBlock>Hello world</TextBlock>
</Page>
下列範例示範如何實作Mica材質概觀中顯示的標準分層模式。 每個範例都會使用 ,而且需要相同的標題列代碼後置,如上一個範例所示。
根據預設, 左側模式中的 NavigationView 會在其內容區域中包含內容層。 本範例會將 Mica 延伸至標題列區域,並建立自訂標題列。
<Page
x:Class="LeftNavView.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:LeftNavView"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
mc:Ignorable="d"
muxc:BackdropMaterial.ApplyToRootOrPageBackground="True">
<Page.Resources>
<!--This top margin is the height of the custom TitleBar-->
<Thickness x:Key="NavigationViewContentMargin">0,48,0,0</Thickness>
</Page.Resources>
<Grid>
<Border x:Name="AppTitleBar"
IsHitTestVisible="True"
VerticalAlignment="Top"
Background="Transparent"
Height="48"
Canvas.ZIndex="1"
Margin="48,0,0,0">
<StackPanel Orientation="Horizontal">
<Image x:Name="AppFontIcon"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Source="Assets/Square44x44Logo.png"
Width="16"
Height="16"/>
<TextBlock x:Name="AppTitle"
Text="Test App Title"
VerticalAlignment="Center"
Margin="12, 0, 0, 0"
Style="{StaticResource CaptionTextBlockStyle}" />
</StackPanel>
</Border>
<muxc:NavigationView x:Name="NavigationViewControl"
IsTitleBarAutoPaddingEnabled="False"
IsBackButtonVisible="Visible"
Header="Title"
DisplayModeChanged="NavigationViewControl_DisplayModeChanged"
Canvas.ZIndex="0">
<muxc:NavigationView.MenuItems>
<muxc:NavigationViewItem Icon="Target" Content="Text"/>
<muxc:NavigationViewItem Icon="Target" Content="Text"/>
<muxc:NavigationViewItem Icon="Target" Content="Text"/>
<muxc:NavigationViewItem Icon="Target" Content="Text"/>
<muxc:NavigationViewItem Icon="Target" Content="Text"/>
</muxc:NavigationView.MenuItems>
<Grid>
<Frame x:Name="contentFrame">
<Grid>
<TextBlock Padding="56,16,0,0">Page content!</TextBlock>
</Grid>
</Frame>
</Grid>
</muxc:NavigationView>
</Grid>
</Page>
根據預設, Top 模式中的 NavigationView 會在其內容區域中包含內容層。 本範例會將 Mica 延伸至標題列區域,並建立自訂標題列。
<Page
x:Class="TopNavView.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:TopNavView"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
mc:Ignorable="d"
muxc:BackdropMaterial.ApplyToRootOrPageBackground="True">
<Page.Resources>
<CornerRadius x:Key="NavigationViewContentGridCornerRadius">0</CornerRadius>
</Page.Resources>
<Grid>
<Border x:Name="AppTitleBar"
IsHitTestVisible="True"
VerticalAlignment="Top"
Background="Transparent"
Height="32"
Margin="48,0,0,0">
<StackPanel Orientation="Horizontal">
<Image x:Name="AppFontIcon"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Source="Assets/Square44x44Logo.png"
Width="16"
Height="16"/>
<TextBlock x:Name="AppTitle"
Text="Test App Title"
VerticalAlignment="Center"
Margin="12,0,0,0"
Style="{StaticResource CaptionTextBlockStyle}" />
</StackPanel>
</Border>
<muxc:NavigationView x:Name="NavigationViewControl"
Header="Page Title"
DisplayModeChanged="NavigationViewControl_DisplayModeChanged"
PaneDisplayMode="Top">
<muxc:NavigationView.MenuItems>
<muxc:NavigationViewItem Content="Text"/>
<muxc:NavigationViewItem Content="Text"/>
<muxc:NavigationViewItem Content="Text"/>
<muxc:NavigationViewItem Content="Text"/>
<muxc:NavigationViewItem Content="Text"/>
</muxc:NavigationView.MenuItems>
<Grid>
<Frame x:Name="contentFrame">
<Grid>
<TextBlock Padding="56,16,0,0">Page content!</TextBlock>
</Grid>
</Frame>
</Grid>
</muxc:NavigationView>
</Grid>
</Page>
若要使用 NavigationView 遵循卡片模式,您必須覆寫背景和框線主題資源來移除預設內容層。 然後,您可以在控制項的內容區域中建立卡片。 此範例會建立數張卡片、將 Mica 延伸至標題列區域,並建立自訂標題列。 如需卡片 UI 的詳細資訊,請參閱分層和標高指引。
<Page
x:Class="CardLayout.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:CardLayout"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
mc:Ignorable="d"
muxc:BackdropMaterial.ApplyToRootOrPageBackground="True">
<Page.Resources>
<!--This top margin is the height of the custom TitleBar-->
<Thickness x:Key="NavigationViewContentMargin">0,48,0,0</Thickness>
<Thickness x:Key="NavigationViewContentGridBorderThickness">0</Thickness>
<SolidColorBrush x:Key="NavigationViewContentBackground" Color="Transparent"></SolidColorBrush>
</Page.Resources>
<Grid>
<Border x:Name="AppTitleBar"
IsHitTestVisible="True"
VerticalAlignment="Top"
Background="Transparent"
Height="48"
Canvas.ZIndex="1"
Margin="48,0,0,0">
<StackPanel Orientation="Horizontal">
<Image x:Name="AppFontIcon"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Source="Assets/Square44x44Logo.png"
Width="16"
Height="16"/>
<TextBlock x:Name="AppTitle"
Text="Test App Title"
VerticalAlignment="Center"
Margin="12,0,0,0"
Style="{StaticResource CaptionTextBlockStyle}" />
</StackPanel>
</Border>
<muxc:NavigationView x:Name="NavigationViewControl"
IsTitleBarAutoPaddingEnabled="False"
IsBackButtonVisible="Visible"
Header="Title"
DisplayModeChanged="NavigationViewControl_DisplayModeChanged"
Canvas.ZIndex="0">
<muxc:NavigationView.MenuItems>
<muxc:NavigationViewItem Icon="Target" Content="Text"/>
<muxc:NavigationViewItem Icon="Target" Content="Text"/>
<muxc:NavigationViewItem Icon="Target" Content="Text"/>
<muxc:NavigationViewItem Icon="Target" Content="Text"/>
<muxc:NavigationViewItem Icon="Target" Content="Text"/>
</muxc:NavigationView.MenuItems>
<Grid>
<Frame x:Name="contentFrame">
<StackPanel Orientation="Vertical" Margin="40,16,0,0">
<Border Width="600" Height="200" Background="{ThemeResource LayerFillColorDefaultBrush}"
VerticalAlignment="Top"
HorizontalAlignment="Left"
Margin="16"
CornerRadius="8"
BorderThickness="1"
BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}">
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center">Content here!</TextBlock>
</Border>
<Border Width="600" Height="200" Background="{ThemeResource LayerFillColorDefaultBrush}"
VerticalAlignment="Top"
HorizontalAlignment="Left"
Margin="16"
CornerRadius="8"
BorderThickness="1"
BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}">
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center">Content here!</TextBlock>
</Border>
<Border Width="600" Height="200" Background="{ThemeResource LayerFillColorDefaultBrush}"
VerticalAlignment="Top"
HorizontalAlignment="Left"
Margin="16"
CornerRadius="8"
BorderThickness="1"
BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}">
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center">Content here!</TextBlock>
</Border>
</StackPanel>
</Frame>
</Grid>
</muxc:NavigationView>
</Grid>
</Page>
前三個應用程式配置 XAML 頁面使用此後置程式碼來建立適應應用程式狀態和可見性的自訂標題列。
如需詳細資訊,請參閱標題列自訂。
public MainPage()
{
this.InitializeComponent();
var titleBar = ApplicationView.GetForCurrentView().TitleBar;
titleBar.ButtonBackgroundColor = Colors.Transparent;
titleBar.ButtonInactiveBackgroundColor = Colors.Transparent;
// Hide default title bar.
var coreTitleBar = CoreApplication.GetCurrentView().TitleBar;
coreTitleBar.ExtendViewIntoTitleBar = true;
UpdateTitleBarLayout(coreTitleBar);
// Set XAML element as a draggable region.
Window.Current.SetTitleBar(AppTitleBar);
// Register a handler for when the size of the overlaid caption control changes.
// For example, when the app moves to a screen with a different DPI.
coreTitleBar.LayoutMetricsChanged += CoreTitleBar_LayoutMetricsChanged;
// Register a handler for when the title bar visibility changes.
// For example, when the title bar is invoked in full screen mode.
coreTitleBar.IsVisibleChanged += CoreTitleBar_IsVisibleChanged;
//Register a handler for when the window changes focus
Window.Current.Activated += Current_Activated;
}
private void CoreTitleBar_LayoutMetricsChanged(CoreApplicationViewTitleBar sender, object args)
{
UpdateTitleBarLayout(sender);
}
private void UpdateTitleBarLayout(CoreApplicationViewTitleBar coreTitleBar)
{
// Update title bar control size as needed to account for system size changes.
AppTitleBar.Height = coreTitleBar.Height;
// Ensure the custom title bar does not overlap window caption controls
Thickness currMargin = AppTitleBar.Margin;
AppTitleBar.Margin = new Thickness(currMargin.Left, currMargin.Top, coreTitleBar.SystemOverlayRightInset, currMargin.Bottom);
}
private void CoreTitleBar_IsVisibleChanged(CoreApplicationViewTitleBar sender, object args)
{
if (sender.IsVisible)
{
AppTitleBar.Visibility = Visibility.Visible;
}
else
{
AppTitleBar.Visibility = Visibility.Collapsed;
}
}
// Update the TitleBar based on the inactive/active state of the app
private void Current_Activated(object sender, Windows.UI.Core.WindowActivatedEventArgs e)
{
SolidColorBrush defaultForegroundBrush = (SolidColorBrush)Application.Current.Resources["TextFillColorPrimaryBrush"];
SolidColorBrush inactiveForegroundBrush = (SolidColorBrush)Application.Current.Resources["TextFillColorDisabledBrush"];
if (e.WindowActivationState == Windows.UI.Core.CoreWindowActivationState.Deactivated)
{
AppTitle.Foreground = inactiveForegroundBrush;
}
else
{
AppTitle.Foreground = defaultForegroundBrush;
}
}
// Update the TitleBar content layout depending on NavigationView DisplayMode
private void NavigationViewControl_DisplayModeChanged(Microsoft.UI.Xaml.Controls.NavigationView sender, Microsoft.UI.Xaml.Controls.NavigationViewDisplayModeChangedEventArgs args)
{
const int topIndent = 16;
const int expandedIndent = 48;
int minimalIndent = 104;
// If the back button is not visible, reduce the TitleBar content indent.
if (NavigationViewControl.IsBackButtonVisible.Equals(Microsoft.UI.Xaml.Controls.NavigationViewBackButtonVisible.Collapsed))
{
minimalIndent = 48;
}
Thickness currMargin = AppTitleBar.Margin;
// Set the TitleBar margin dependent on NavigationView display mode
if (sender.PaneDisplayMode == Microsoft.UI.Xaml.Controls.NavigationViewPaneDisplayMode.Top)
{
AppTitleBar.Margin = new Thickness(topIndent, currMargin.Top, currMargin.Right, currMargin.Bottom);
}
else if (sender.DisplayMode == Microsoft.UI.Xaml.Controls.NavigationViewDisplayMode.Minimal)
{
AppTitleBar.Margin = new Thickness(minimalIndent, currMargin.Top, currMargin.Right, currMargin.Bottom);
}
else
{
AppTitleBar.Margin = new Thickness(expandedIndent, currMargin.Top, currMargin.Right, currMargin.Bottom);
}
}