Mica 材质

云母是一种不透明的动态材料,它将主题和桌面壁纸相结合来绘制应用和设置等长期存在的窗口的背景。 你可以将 Mica 应用到应用程序背景中,通过提高用户对焦点的清晰度来取悦用户并创建视觉层次结构,从而提高生产力。 Mica 是专门为应用的性能优化而设计的,它只对桌面壁纸进行一次采样,就可创建其可视化效果。 云母效果适用于使用 WinUI 2 的 UWP 应用和使用 Windows 应用 SDK 1.1(或更高版本)的应用,同时在 Windows 11 版本 22000 或更高版本上运行。

主图

浅色主题中的云母效果
浅色主题中的云母效果

深色主题的 Mica
深色主题的 Mica

云母 Alt 是云母效果的变体,对用户桌面背景色的着色更强。 可将云母 Alt 应用于应用的背景,来提供比云母效果更深的视觉层次结构,尤其是在创建具有选项卡式标题栏的应用时。 云母 Alt 适用于使用 Windows 应用 SDK 1.1 或更高版本的应用,同时在 Windows 11 版本 22000 或更高版本上运行。

下面的图像显示了具有选项卡的标题栏中云母效果和云母 Alt 效果之间的区别。 这一张图使用云母效果,第二张图使用云母 Alt 效果。

具有选项卡的标题栏中的云母效果屏幕截图。

具有选项卡的标题栏中的云母 Alt 效果屏幕截图。

何时使用云母或云母 Alt 效果

云母和云母 Alt 是在应用程序背景中显示的材料,它们显示在所有其他内容的下面。 每种材料都是不透明的,它们将用户的主题和桌面壁纸相结合,创建高度个性化的外观。 随着用户在屏幕上移动窗口,Mica 材质会动态调整,以便使用应用程序下的壁纸创建丰富的可视化效果。 此外,如果应用处于非活动状态,该材质可以通过回退到中性色来帮助用户专注于当前任务。

建议将云母或云母 Alt 效果用作应用的基层,并在标题栏区域中确定显示优先级。 有关更具体的分层指导,请参阅分层和提升以及通过 Mica 实现应用分层

可用性和适应性

云母材料自动适应各种设备和上下文。 它们专为性能而设计,因为它们只捕获一次背景壁纸来创建其可视化效果。

在高对比度模式下,用户将继续看到他们选择的熟悉背景色,而不是云母或云母 Alt 效果。此外,在以下情况中,云母材料显示为纯色备选色(SolidBackgroundFillColorBase 表示云母效果,SolidBackgroundFillColorBaseAlt 表示云母 Alt 效果):

  • 用户关闭“设置”>“个性化设置”>“颜色”中的透明度。
  • 启用节电模式。
  • 应用在低端硬件上运行。
  • 桌面上的应用窗口停用。
  • Windows 应用在 Xbox 或 HoloLens 上运行。
  • Windows 版本低于 22000。

通过 Mica 实现应用分层

标准模式内容层
标准内容层

卡片模式内容层
卡片模式内容层

Mica 非常适合作为应用层次结构中的基础层,因为它具有非活动状态和活动状态并可进行轻微的个性化设置。 若要采用包含两层的分层和提升系统,建议将云母效果用作应用的基层,并另外添加一个位于基层顶部的内容层。 内容层应使用 LayerFillColorDefaultBrush (一种低不透明度纯色)作为背景来选取其后面的材质 Mica。 建议的内容层模式如下:

  • 标准模式:大面积区域的连续背景,需要与基础层区别开来的层次结构。 应将 LayerFillColorDefaultBrush 应用于 WinUI 应用表面(例如网格、堆叠面板、框架等)的容器背景。
  • 卡片模式:分段式卡片,适用于设计有多个分节和不连续 UI 组件的应用。 有关使用 LayerFillColorDefaultBrush 的卡片 UI 的定义,请参阅分层和提升指南。

若要使应用的窗口具有无缝的外观,Mica 应显示在标题栏中(如果选择将此材质应用到应用)。 可以通过将应用扩展到非客户端区域,并创建透明的自定义标题栏来在标题栏中显示 Mica。 有关详细信息,请参阅标题栏

下面的示例展示了具有 NavigationView 的分层策略的常见实现,其中标题栏区域中显示云母效果。

  • 左侧 NavigationView 中的标准模式。
  • 顶部 NavigationView 中的标准模式。
  • 左侧 NavigationView 中的卡片模式。

左侧 NavigationView 中的标准模式

默认情况下,左侧 NavigationView 模式在内容区域中包含内容层。 此示例将 Mica 扩展到标题栏区域中,并创建自定义标题栏。

标准模式中的导航视图,自定义标题栏处于左侧模式下

顶部 NavigationView 中的标准模式

默认情况下,顶部 NavigationView 模式在内容区域中包含内容层。 此示例将 Mica 扩展到标题栏区域中,并创建自定义标题栏。

标准模式中的导航视图,自定义标题栏处于顶部模式下

左侧 NavigationView 中的卡片模式

若要使用 NavigationView 遵循卡片模式,需要通过覆盖背景和边框主题资源来删除默认内容层。 然后,可以在控件的内容区域中创建卡片。 此示例会创建多个卡片、将 Mica 扩展到标题栏区域中,并创建自定义标题栏。 有关卡片 UI 的详细信息,请参阅分层和提升指南。

标准模式中的导航视图,自定义标题栏处于左侧模式下

采用云母 Alt 效果的应用分层

云母 Alt 可替代云母效果用作应用层次结构中的基础层,它拥有相同的功能,例如非活动状态、活动状态和细微个性化。 如果需要标题栏元素与应用的命令区域(例如导航、菜单)之间有对比度,建议将云母 Alt 用作应用的基层。

使用云母 Alt 的一种常见场景是在创建具有选项卡式标题栏的应用程序时。 若要按照分层和提升指南进行操作,建议将云母 Alt 用作应用的基层,添加一个位于基层顶部的命令层,最后另外添加一个位于命令层顶部的内容层。 命令层应使用 LayerOnMicaBaseAltFillColorDefaultBrush(一种低不透明度纯色)作为背景来选取它下面的材料 - 云母 Alt。 内容层应使用 LayerFillColorDefaultBrush (另一种低不透明度纯色)来选取它下面的图层。 图层系统如下所示:

  • 云母 Alt
  • 命令层:需要与基层有明显的层次区别。 必须将 LayerOnMicaBaseAltFillColorDefaultBrush 应用于 WinUI 应用表面的命令区域(例如菜单栏、导航结构等)
  • 内容层:大面积区域的连续背景,需要与命令层有明显的层次区别。 应将 LayerFillColorDefaultBrush 应用于 WinUI 应用表面(例如网格、堆叠面板、框架等)的容器背景。

若要使应用的窗口具有顺畅的外观,标题栏中应显示云母 Alt 效果(如果你选择对应用使用材料)。 可通过将应用扩展到非客户端区域,并创建透明的自定义标题栏,在标题栏中显示云母 Alt 效果。

建议

  • 请将背景材料应用于最下面的图层(如果存在 ApplicationPageBackgroundThemeBrush,则替代它)。
  • 应将希望看到 Mica 的所有背景层设置为“透明”,以便 Mica 能够显示。
  • 请勿在应用程序中多次使用背景材料。
  • 请勿将背景材料应用于 UI 元素。 背景材质不会显示在元素本身上。 只有 UI 元素和窗口之间的所有层均设置为透明时,它才会显示。

如何使用 Mica

可在使用 WinUI 2 的 UWP 应用或使用 Windows 应用 SDK 1.1(或更高版本)的应用中使用云母效果。 可在使用 Windows 应用 SDK 1.1 或更高版本的应用中使用云母 Alt 效果。

将云母效果用于 Windows 应用 SDK

若要在使用 Windows 应用 SDK 和 WinUI 3 的 XAML 应用中使用云母效果,请将 Window.SystemBackdrop 属性设置为 MicaBackdrop

以下示例演示如何在 XAML 和代码中执行此操作。

Mica

<Window
    ... >

    <Window.SystemBackdrop>
        <MicaBackdrop Kind="BaseAlt"/>
    </Window.SystemBackdrop>

</Window>
public MainWindow()
{
    this.InitializeComponent();

    SystemBackdrop = new MicaBackdrop() 
                        { Kind = MicaKind.BaseAlt };
}

若要详细了解如何使用 Composition MicaController API,请参阅在 Windows 11 的桌面设备中应用云母或亚克力材料

若要在 Win32 应用中使用背景材料,请参阅在 Windows 11 的 Win32 桌面应用中使用云母效果

将云母效果用于 WinUI 2 for UWP

重要的 API:BackdropMaterial 类

可通过 BackdropMaterial 类在 UWP 应用中使用云母效果。 建议在作为 XAML 内容的根的 XAML 元素上设置 BackdropMaterial 附加属性,因为该属性将应用于整个内容区域(例如窗口)。 如果应用具有导航多个页面的框架,则应在框架上设置此属性。 否则,应在应用的页面上设置此属性。

<Page muxc:BackdropMaterial.ApplyToRootOrPageBackground="True">
    <TextBlock>Hello world</TextBlock>
</Page>

以下示例演示如何实现前面所示的标准分层模式。 其中的每个示例都使用并要求相同的标题栏后置代码,如最后一个示例中所示。

示例:左侧导航视图中的标准模式

默认情况下,左侧 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>

示例:顶部导航视图中的标准模式

默认情况下,顶部 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);
    }
}