Mica 材质

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

主图

浅色主题
Mica 浅色主题中的 Mica

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

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

这些图像显示了具有选项卡的标题栏中 Mica 和 Mica Alt 之间的差异。 第一个图像使用 Mica,第二个图像使用 Mica Alt。

标题栏中具有选项卡的 Mica 的屏幕截图。

标题栏中带有选项卡的 Mica Alt 的屏幕截图。

何时使用 Mica 或 Mica Alt

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

建议应用 Mica 或 Mica Alt 作为应用的基础层,并在标题栏区域中确定可见性的优先级。 有关更具体的分层指导,请参阅分层和提升以及通过 Mica 实现应用分层

可用性和适应性

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

在高对比度模式下,用户将继续看到他们选择的熟悉背景色,以取代 Mica 或 Mica Alt。此外,Mica 材料将显示为纯色回退颜色 (SolidBackgroundFillColorBase for Mica,SolidBackgroundFillColorBaseAlt for Mica Alt) 以下情况下:

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

通过 Mica 实现应用分层

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

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

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

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

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

以下示例演示了 使用 NavigationView 的分层策略的常见实现,其中 Mica 在标题栏区域中可见。

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

左侧 NavigationView 中的标准模式

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

在左侧模式下使用自定义标题栏的标准模式导航视图

顶部 NavigationView 中的标准模式

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

在顶部模式下使用自定义标题栏的标准模式的 NavigationView

左侧 NavigationView 中的卡片模式

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

标准模式中的 NavigationView,左侧模式下具有自定义标题栏

使用 Mica Alt 的应用分层

Mica Alt 是作为应用层次结构中基础层的 Mica 的替代方法,其功能相同,如非活动状态和细微的个性化。 当需要标题栏元素与应用的命令区域之间 ((例如导航、菜单) )之间形成对比度时,建议应用 Mica Alt 作为应用的基础层。

使用 Mica Alt 的常见方案是在创建具有选项卡式标题栏的应用程序时。 若要遵循 分层和提升 指南,我们建议将 Mica Alt 应用为应用的基础层,添加位于基础层顶部的命令层,最后添加位于命令层顶部的其他内容层。 命令层应选取其后面的材料 Mica Alt,使用 LayerOnMicaAltFillColorDefaultBrush(低不透明度纯色)作为背景。 内容层应使用另一种低不透明度纯色 LayerFillColorDefaultBrush 选取其下方的图层。 层系统如下所示:

  • Mica Alt
  • 命令层:需要与基础层不同的分层差异。 LayerOnMicaAltFillColorDefaultBrush 应应用于 WinUI 应用图面 (的命令区域,例如菜单栏、导航结构等)
  • 内容层:需要与命令层不同的层次结构区分的大型区域的连续背景。 应将 LayerFillColorDefaultBrush 应用于 WinUI 应用表面(例如网格、堆叠面板、框架等)的容器背景。

若要使应用的窗口具有无缝外观,如果选择将材料应用于应用,则应在标题栏中显示 Mica Alt。 可以通过将应用扩展到非工作区并创建透明的自定义标题栏,在标题栏中显示 Mica Alt。

建议

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

如何使用 Mica

可以在使用 WinUI 2 的 UWP 应用中,或使用 Windows 应用 SDK 1.1 或更高版本的应用中使用 Mica。 可以在使用 Windows 应用 SDK 1.1 或更高版本的应用中使用 Mica Alt。

将 Mica 与 Windows 应用 SDK

若要在使用 Windows 应用 SDK 和 WinUI 3 的 XAML 应用中使用背景材料,请参阅在桌面应用中应用 Mica 或 Acrylic 材料以Windows 11

若要在 Win32 应用中使用背景材料,请参阅在 Win32 桌面应用中应用 Mica Windows 11

将 Mica 与适用于 UWP 的 WinUI 2 配合使用

重要的 API:BackdropMaterial 类

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

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

以下示例演示如何实现前面所示的标准分层模式。 每个示例都使用 并需要相同的标题条形码隐藏,如最后一个示例所示。

示例:Left NavigationView 中的标准模式

默认情况下,左侧 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="40"
                Canvas.ZIndex="1" 
                Margin="48,8,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 中的标准模式

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

示例:Left NavigationView 中的卡片模式

若要使用 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="40"
                Canvas.ZIndex="1" 
                Margin="48,8,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);
    }
}