AMG
AMG

Reputation: 146

Adding an InfoBadge to NavigationViewItem

For some reason, InfoBadge can't be found in the NavigationViewItem type. I'm using the WinUI 3 template project and the documentation at https://learn.microsoft.com/en-us/windows/apps/design/controls/info-badge makes it seem like it's supported in WinUI 3.

<NavigationViewItem
    x:Uid="Shell_PurchaseOrders"
    helpers:NavigationHelper.NavigateTo="NewUITest.ViewModels.PurchaseOrdersViewModel">
    <NavigationViewItem.Icon>
        <FontIcon
            FontFamily="{StaticResource SymbolThemeFontFamily}"
            Glyph="&#xea37;"/>
    </NavigationViewItem.Icon>
    <NavigationViewItem.InfoBadge>
        <InfoBadge
            x:Name="bg1"
            Value="1"
            Visibility="true"/>
    </NavigationViewItem.InfoBadge>
</NavigationViewItem>

Do I have to add any other references?

x:Class="NewUITest.Views.ShellPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:helpers="using:NewUITest.Helpers"
xmlns:behaviors="using:NewUITest.Behaviors"
xmlns:i="using:Microsoft.Xaml.Interactivity"
Loaded="OnLoaded">

Upvotes: 0

Views: 441

Answers (1)

Andrew KeepCoding
Andrew KeepCoding

Reputation: 13536

UPDATE

As I mentioned in the comments, unfortunately InfoBadge is not available in WinUI 3 (yet?).

InfoBadge is available since WinAppSDKv1.2. So you don't need the workaround below.

Workaround for WinAppSDKv1.1

Meanwhile, you can create a customized NavigationViewItem:

using Microsoft.UI;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media;
using Microsoft.UI.Xaml.Shapes;
using System;
using Windows.UI;

namespace CustomControls;

[TemplatePart(Name = nameof(NVIRootGrid), Type = typeof(Grid))]
public sealed class NavigationViewItemWithInfoBadge : NavigationViewItem
{
    public static readonly DependencyProperty ShowDotInfoBadgeProperty = DependencyProperty.Register(
        nameof(ShowDotInfoBadge),
        typeof(bool),
        typeof(NavigationViewItemWithInfoBadge),
        new PropertyMetadata(default, OnShowDotInfoBadgePropertyChanged));

    public static readonly DependencyProperty InfoBadgeBackgroundProperty = DependencyProperty.Register(
        nameof(InfoBadgeBackground),
        typeof(Brush),
        typeof(NavigationViewItemWithInfoBadge),
        new PropertyMetadata(default, OnInfoBadgeBackgroundPropertyChanged));

    public bool ShowDotInfoBadge
    {
        get => (bool)GetValue(ShowDotInfoBadgeProperty);
        set => SetValue(ShowDotInfoBadgeProperty, value);
    }

    public Brush InfoBadgeBackground
    {
        get => (Brush)GetValue(InfoBadgeBackgroundProperty);
        set => SetValue(InfoBadgeBackgroundProperty, value);
    }

    private Grid? NVIRootGrid { get; set; }

    private Ellipse InfoBadge { get; set; } = new()
    {
        Width = 10,
        Height = 10,
        Margin = new Thickness(10),
        Visibility = Visibility.Collapsed,
        HorizontalAlignment = HorizontalAlignment.Right,
        VerticalAlignment = VerticalAlignment.Top,
    };

    protected override void OnApplyTemplate()
    {
        base.OnApplyTemplate();

        // Get the root Grid of the NavigationViewItem and 
        // add the InfoBadge as its children.
        if (GetTemplateChild(nameof(NVIRootGrid)) is Grid nviRootGrid)
        {
            NVIRootGrid = nviRootGrid;
            NVIRootGrid.Children.Add(InfoBadge);
        }
    }

    private static void OnInfoBadgeBackgroundPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is NavigationViewItemWithInfoBadge control)
        {
            control.InfoBadge.Fill = e.NewValue as Brush;
        }
    }

    private static void OnShowDotInfoBadgePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is NavigationViewItemWithInfoBadge control)
        {
            control.InfoBadge.Visibility = (e.NewValue is bool newValue && newValue is true)
                ? Visibility.Visible
                : Visibility.Collapsed;
        }
    }
}

And use it like this:

<local:NavigationViewItemWithInfoBadge
    Content="Some content"
    InfoBadgeBackground="SkyBlue"
    ShowDotInfoBadge="true" />

Upvotes: 1

Related Questions