信息标记(Info badge)

添加徽章是一种无干扰性且直观的方法,用于显示通知或将注意力集中到应用内的某个区域 - 无论是通知区域、指示新内容还是显示警报的区域。 info badge 是一小块用户界面,可添加到应用中,并进行自定义,以显示数字、图标或简单的一个点。

info badge 内置于 XAML navigation view 中,但也可以作为独立元素放置在 XAML 树中,从而可以将 info badge 置于你选择的任何控件或 UI 块中。 在 navigation view 以外的地方使用 info badge 时,需要负责通过编程确定何时显示和取消 info badge 以及将 info badge 放在何处。

NavigationView 中 InfoBadge 的示例

这是正确的控件吗?

当希望以不干扰的方式将用户的注意力集中到应用程序的某个区域时,则应使用 info badge。 当出现 info badge 时,它的目的是将注意力集中到某个区域,然后让用户重新回到他们的流程中,让他们选择是否查看 info badge 出现的详细原因。 信息徽章只应代表可撤销和非永久性的信息 - info badge 应有具体的规则,规定何时可以出现、消失和更改。

适当的 info badge 用法示例:

  • 指示新消息已送达。
  • 指示可读取的新文章。
  • 表示页面上有新的可用选项。
  • 指示某页面上的项目可能存在问题,但不会阻止应用运行。

何时应该使用不同的控件?

info badge 不应用于显示关键错误或传达需要立即采取行动的非常重要的信息。 如果需要立即与信息徽章互动才能继续使用应用程序,则不应使用信息徽章。

不适当的 info badge 用法示例:

  • 在应用内的一个页面上指示需要处理才能继续使用应用的紧急事项。 对于此方案,请使用 content dialog
  • 在应用程序中出现而用户却无法消除 info badge。 对于这样的持续性警报,请使用 info bar
  • 使用 info badge 作为将用户的焦点带到某个区域的永久性方法,而用户却无法消除 info badge。
  • 在应用中使用 info badge 作为常规图标或图像。 相反,请使用适当的图像或图标(请参阅 IconElementIconSource)。

info badge 的类型

info badge 有三种样式可供选择 - 图标数字,顺序如下所示。

点、图标和数字 InfoBadge

点 info badge

点 info badge 是一个直径为 4px 的简单椭圆。 它无边框,不用于保存文本或其中任何内容。

在一般情况下,应使用点 info badge 引导用户关注 info badge - 例如,表示有可用的新内容或更新。

图标 info badge

图标 info badge 是一个直径为 16px 的椭圆,内部包含一个图标。 info badge 有一个 IconSource 属性,可为支持的图标类型提供灵活性。

应该使用图标 info badge 在引起用户注意的同时发送一条快速信息,例如,提醒用户非阻止性操作出了问题、有一个额外的重要更新可用,或者应用程序中的某些特定功能当前已启用(如倒计时器正在运行)。

如果要在 info badge 的 IconSource 中使用 BitmapIconSource,则必须确保位图适合 info badge 的内部(通过更改图标的大小或更改 info badge 的大小)。

数字 info badge

数字 info badge 的形状和大小与图标 info badge 相同,但其内部包含一个由 Value 属性决定的数字。 数字必须是整数,并且必须大于或等于零。 当显示的数字增加到多位数时,info badge 的宽度会自动扩大,并以平滑的动画效果显示。

应该使用数字 info badge 来表示有特定数量的项目需要关注,例如新邮件或消息。

预设 info badge 样式

为了帮助支持使用 info badge 的最常见场景,该控件包含内置预设 info badge 样式。 虽然可以自定义 info badge 以使用想要的任何颜色/图标/数字组合,但这些内置预设是一个快速选项,可确保 info badge 符合可访问性指南,并在图标和数字大小方面符合比例要求。

以下是 info badge 的预设样式:

Attention

  • AttentionDotInfoBadgeStyle
  • AttentionIconInfoBadgeStyle
  • AttentionValueInfoBadgeStyle

注意 InfoBadge 样式

信息

  • InformationalDotInfoBadgeStyle
  • InformationalIconInfoBadgeStyle
  • InformationalValueInfoBadgeStyle

信息性 InfoBadge 样式

Success

  • SuccessDotInfoBadgeStyle
  • SuccessIconInfoBadgeStyle
  • SuccessValueInfoBadgeStyle

成功 InfoBadge 样式

注意

  • CautionDotInfoBadgeStyle
  • CautionIconInfoBadgeStyle
  • CautionValueInfoBadgeStyle

警告 InfoBadge 样式

严重

  • CriticalDotInfoBadgeStyle
  • CriticalIconInfoBadgeStyle
  • CriticalValueInfoBadgeStyle

重要 InfoBadge 样式

如果在 info badge 上设置了样式,同时又设置了与之冲突的属性,则该属性将覆盖样式中与之冲突的部分,但不冲突的样式元素将继续应用。

例如,如果将 CriticalIconInfoBadgeStyle 应用到 info badge 中,但同时也设置了 InfoBadge.Value = "1",那么最终 info badge 的背景颜色将是“重要”,但会在其中显示数字 1,而不是显示预设图标。

此示例创建的 info badge 采用了 Attention Icon 预设样式的颜色和图标。

<InfoBadge Style="{ThemeResource AttentionIconInfoBadgeStyle}"/>

带有星号的蓝色 InfoBadge

辅助功能

info badge 控件本身不具备任何屏幕阅读器功能或用户界面自动化 (UIA),因为该控件无法聚焦,也无法与之交互。

如果在 navigation view 内使用 info badge,则 navigation view 将提供内置屏幕阅读器和辅助技术支持。 在以标签方式浏览 navigation view 时,如果看到 navigation view 项目上有 info badge,则屏幕阅读器就会显示该项目上有 info badge。 如果有关的 info badge 是数字,屏幕阅读器也会显示 info badge 的值。

如果在 navigation view 之外使用 info badge,我们建议采取以下措施,以确保应用程序完全可访问:

  • info badge 的父元素应可聚焦,并可通过选项卡访问。
  • 父元素会向屏幕阅读器显示 info badge。
  • 当 info badge 首次出现时,应用程序会发送 UIA 通知。
  • 当 info badge 从用户界面消失时,应用会发送 UIA 通知。
  • 当现有 info badge 发生重大变更时,应用会发送 UIA 通知。
    • “重大更改”的定义取决于每个开发人员。 这方面的示例包括:info badge 在不同类型之间切换,info badge 改变颜色以表示其状态,或 info badge 的值超过某个有效数字。

要控制父元素向屏幕阅读器显示的内容,可以使用 AutomationProperties 类的附加属性。 对于 info badge,建议在父元素上设置 AutomationProperties.FullDescriptionAutomationProperties.ItemStatus 附加属性。

要在 info badge 出现或消除时发送 UIA 通知,可以使用 AutomationPeer.RaiseAutomationEvent 方法。

info badge 的默认大小符合可访问性要求。 可以自定义 info badge 的许多方面,包括其高度/宽度/颜色等,但重要的是,默认 info badge 必须遵守我们的可访问性指南中关于大小和颜色的规定。

UWP 和 WinUI 2

重要

本文中的信息和示例是针对使用 Windows App SDKWinUI 3 的应用优化的,但通常适用于使用 WinUI 2 的 UWP 应用。 有关特定于平台的信息和示例,请查看 UWP API 参考。

本部分包含在 UWP 或 WinUI 2 应用中使用该控件所需的信息。

UWP 应用的 InfoBadge 需要 WinUI 2。 有关详细信息(包括安装说明),请参阅 WinUI 2。 此控件的 API 存在于 Microsoft.UI.Xaml.Controls 命名空间中。

要将本文中的代码与 WinUI 2 配合使用,请使用 XAML 中的别名(我们使用 muxc)来表示项目中包含的 Windows UI 库 API。 有关详细信息,请参阅 WinUI 2 入门

xmlns:muxc="using:Microsoft.UI.Xaml.Controls"

<muxc:InfoBadge/>

创建 InfoBadge

重要

一些信息与预发行产品相关,相应产品在发行之前可能会进行重大修改。 对于此处提供的信息,Microsoft 不作任何明示或暗示的担保。

WinUI 3 库应用包括大多数 WinUI 3 控件、特性和功能的交互式示例。 通过 Microsoft Store 获取应用,或在 GitHub 上获取源代码

可以在 XAML 或代码中创建 InfoBadge。 创建的 InfoBadge 类型由你设置的属性决定。

要创建点 InfoBadge,请使用未设置任何属性的默认 InfoBadge 控件。

<InfoBadge />

点 InfoBadge

图标

要创建图标 InfoBadge,请设置 IconSource 属性。

<InfoBadge x:Name="SyncStatusInfoBadge">
    <InfoBadge.IconSource>
        <SymbolIconSource Symbol="Sync"/>
    </InfoBadge.IconSource>
</InfoBadge>

图标 InfoBadge

数字

要创建数字 InfoBadge,请设置 Value 属性。

<InfoBadge x:Name="EmailInfoBadge" Value="{x:Bind numUnreadMail}"/>

数字 InfoBadge

在大多数情况下,将 InfoBadge 的 Value 属性绑定到应用后端中不断变化的整数值,这样你就可以根据该特定值轻松增加/减少和显示/隐藏 InfoBadge。

注意

如果同时设置了 IconValue 属性,则属性 Value 优先,InfoBadge 显示为数字 InfoBadge。

在 NavigationView 中使用 InfoBadge

如果在应用中使用 NavigationView,建议使用 NavigationView 中的 InfoBadge 来显示应用范围内的通知和警报。 要将 InfoBadge 放在 NavigationViewItem 上,请为 NavigationViewItem.InfoBadge 属性分配 InfoBadge 对象。

在左展开模式下,InfoBadge 与 NavigationViewItem 的边缘右对齐。

带有 InfoBadge 的左侧展开的 NavigationView

在左紧密模式下,InfoBadge 叠加显示在图标右上角。

带有 InfoBadge 的左侧紧凑的 NavigationView

在顶部模式下,InfoBadge 与整个项的右上角对齐。

带有 InfoBadge 的顶部模式 NavigationView

建议不要在同一个 NavigationView 中使用不同类型的 InfoBadge,例如,将数字 InfoBadge 附加到一个 NavigationViewItem,将点 InfoBadge 附加到同一 NavigationView 中的另一个 NavigationViewItem。

示例:在 NavigationView 中增加一个数字 InfoBadge

此示例模拟电子邮件应用如何在 NavigationView 中使用 InfoBadge 来显示收件箱中新电子邮件的数量,并在收到新邮件时增加 InfoBadge 中显示的数字。

<NavigationView SelectionChanged="NavigationView_SelectionChanged">
    <NavigationView.MenuItems>
        <NavigationViewItem Content="Home" Icon="Home"/>
        <NavigationViewItem Content="Account" Icon="Contact"/>
        <NavigationViewItem x:Name="InboxPage" Content="Inbox" Icon="Mail">
            <NavigationViewItem.InfoBadge>
                <InfoBadge x:Name="bg1"
                                Value="{x:Bind mailBox.NewMailCount, Mode=OneWay}"
                                Visibility="{x:Bind mailBox.HasNewMail, Mode=OneWay}"/>
            </NavigationViewItem.InfoBadge>
        </NavigationViewItem>
    </NavigationView.MenuItems>
    <Frame x:Name="contentFrame" />
</NavigationView>
public sealed partial class MainWindow : Window
{
    MailBox mailBox = new MailBox();

    public MainWindow()
    {
        this.InitializeComponent();

    }

    private void NavigationView_SelectionChanged(NavigationView sender,
                               NavigationViewSelectionChangedEventArgs args)
    {
        if (args.SelectedItem == InboxPage)
        {
            mailBox.ResetNewMailCount();
        }
        else
        {
            mailBox.CheckMail();
        }
    }
}

public class MailBox : DependencyObject
{
    DispatcherQueueTimer timer;

    // Dependency Properties for binding.
    public int NewMailCount
    {
        get { return (int)GetValue(NewMailCountProperty); }
        set { SetValue(NewMailCountProperty, value); }
    }
    public static readonly DependencyProperty NewMailCountProperty =
        DependencyProperty.Register("NewMailCount", typeof(int), typeof(MailBox), new PropertyMetadata(0));

    public bool HasNewMail
    {
        get { return (bool)GetValue(HasNewMailProperty); }
        set { SetValue(HasNewMailProperty, value); }
    }
    public static readonly DependencyProperty HasNewMailProperty =
        DependencyProperty.Register("HasNewMail", typeof(bool), typeof(MailBox), new PropertyMetadata(false));

    public MailBox()
    {
        timer = this.DispatcherQueue.CreateTimer();
        timer.Interval = new TimeSpan(15000000);
        timer.Tick += (s, e) =>
        {
            NewMailCount++;
            if (HasNewMail == false) { HasNewMail = true; }
        };
        timer.Start();
    }

    public void ResetNewMailCount()
    {
        NewMailCount = 0;
        HasNewMail = false;
        timer.Stop();
    }

    public void CheckMail()
    {
        timer.Start();
    }
}

在显示数字 17 的收件箱项目上带有 InfoBadge 的 NavigationView

NavigationView 中的层次结构

如果具有分层 NavigationView,而 NavigationViewItems 嵌套在其他 NavigationViewItems 中,则父项将遵循如上所述的相同设计/放置模式。

父项 NavigationViewItem 和子项 NavigationViewItems 都有其自己的 InfoBadge 属性。 可以将父项 InfoBadge 的值绑定到确定子项 InfoBadge 值的因素,例如,在父项 InfoBadge 上显示子项数字 InfoBadge 的总和。

此图像显示了一个分层 NavigationView,其 PaneDisplayMode 设置为顶部,其中顶级(父)项显示数字 InfoBadge。 应用将父项 InfoBadge 设置为表示子项 InfoBadge 中显示的内容,因为子项当前未展开(因此不可见)。

带有 InfoBadge 的分层 NavigationView

在另一个控件中使用 InfoBadge

你可能想要在除 NavigationView 外的应用内的元素上显示警报或通知。 你可能有一个需要特别注意的 ListViewItem 或显示通知的菜单项。 在这些情况下,可以将 InfoBadge 与其他控件直接集成到 UI 中。

InfoBadge 是 UIElement,因此不能用作共享资源。

为此,请像使用任何其他控件一样使用 InfoBadge - 只需在需要的位置添加要显示的 InfoBadge 标记。 由于 InfoBadge 继承自 Control,因此它具有所有内置定位属性,如边距、对齐方式、填充等,可使用这些属性将 InfoBadge 精确定位到需要的位置。

如果将 InfoBadge 放置在另一个控件内(如 ButtonListViewItem),则在将其定位到超出父控件边界框时,可能会裁剪该 InfoBadge。 如果 InfoBadge 在另一个控件内,则不应将 InfoBadge 定位到控件整体边界框的角之外。

示例:将 InfoBadge 放置在另一个控件内

下面是一个按钮,其右上角有一个 InfoBadge,在内容顶部有一个徽章层。 此示例也可以应用于除 Button 外的许多控件 - 它只是简单地展示了如何在另一个 WinUI 控件中放置、定位和显示 InfoBadge。

<Button Width="200" Height="60" Padding="4"
        HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch">
    <Grid>
        <SymbolIcon Symbol="Sync"/>
        <InfoBadge x:Name="buttonInfoBadge"
                        Background="#C42B1C"
                        HorizontalAlignment="Right" 
                        VerticalAlignment="Top"
                        Width="16" Height="16">
            <InfoBadge.IconSource>
                <FontIconSource Glyph="&#xEA6A;"/>
            </InfoBadge.IconSource>
        </InfoBadge>
    </Grid>
</Button>

带有图标 InfoBadge 的按钮

管理 InfoBadge

InfoBadge 通常显示暂时性警报,因此通常会显示或隐藏它,并在应用运行时定期更改其样式。

显示和隐藏 InfoBadge

可以使用 Visibility 属性或 Opacity 属性根据用户操作、程序逻辑、计数器等显示和隐藏 InfoBadge。

与其他 UIElement 一样,设置 Visibility.Collapsed 使 InfoBadge 不会占用布局中的空间,因此可能会导致在它显示和隐藏时其他元素移动。

如果要重新定位的元素是一个问题,则可以使用 Opacity 属性来显示和隐藏 InfoBadge。 Opacity 默认设置为 1.0;可以将其设置为 0 以隐藏 InfoBadge。 使用 Opacity 属性时,InfoBadge 仍将占用布局中的空间,即使它当前处于隐藏状态。

更改 InfoBadge 样式

可以在显示 InfoBadge 时更改其中显示的图标或数字。 可以通过更改 InfoBadge.Value 的值,实现根据用户操作来增加或减少数字 InfoBadge。 可以通过将 InfoBadge.IconSource 设置为新 IconSource 对象来更改 InfoBadge 的图标。 更改图标时,请确保新图标的大小与旧图标大小相同,以避免产生不和谐的视觉效果。

默认行为

如果未设置 InfoBadge.ValueInfoBadge.IconSource,InfoBadge 将默认显示一个点(特别是当 Value 设置为 -1IconSource 设置为 null 时,这是默认值)。 如果同时设置了 ValueIconSource,则 InfoBadge 将遵循 Value 属性并显示数值。

还可以在显示 InfoBadge 时更改其类型。 要更改 InfoBadge 类型,请确保将当前类型的相应属性(ValueIconSource)设置为其默认值(-1null),并将新类型的属性设置为合适的值。 要将 InfoBadge 类型从数字或图标更改为点类型 InfoBadge,请确保 InfoBadge.Value 设置为 -1,并且 InfoBadge.IconSource 设置为 null

请注意,这可能会导致项随着 InfoBadge 的大小和形状的变化而移动,具体取决于 InfoBadge 的定位方式。