Home > Enterprise >  Typo resistant NavigationViewItem.Tag in WinUI 3
Typo resistant NavigationViewItem.Tag in WinUI 3

Time:12-12

I am trying pass type argument to Tag attribute of NavigationViewItem element in XAML:

<Page
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:page="using:MyApp.Pages"
>
    <NavigationView>
        <NavigationView.MenuItems>
            <NavigationViewItem Content="Test page" Tag="{x:Type page:TestPage}" Icon="Library" />
        </NavigationView.MenuItems>
        <Frame x:Name="contentFrame" />
    </NavigationView>
</Page>

With error: "The Type x:Type was not found.".

When I create custom extension for this:

using Microsoft.UI.Xaml.Markup;
using System;

namespace MyApp.Xaml
{
    [MarkupExtensionReturnType(ReturnType = typeof(Type))]
    public sealed class TypeExtension : MarkupExtension
    {
        public Type Type { get; set; }

        public TypeExtension(Type type)
        {
            Type = type;
        }

        protected override object ProvideValue() => Type;
    }
}

And use it like this:

<Page
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:t="using:MyApp.Xaml"
    xmlns:page="using:MyApp.Pages"
>

    <NavigationView >
        <NavigationView.MenuItems>
            <NavigationViewItem Content="Test page" Tag="{t:Type page:TestPage}" Icon="Library" />
        </NavigationView.MenuItems>
        <Frame x:Name="contentFrame" />
    </NavigationView>
</Page>

It is still not working with error:

Error   WMC0100 XAML TypeExtension type cannot be constructed. In order to be constructed in XAML, a type cannot be abstract, interface, nested, generic or a struct, and must have a public default constructor.

Does anyone have any ideas how to solve passing Type to Tag attribute or another solution to prevent typos in class names?

For completness my selection change handler:

        private void MainNavigationView_SelectionChanged(NavigationView sender, NavigationViewSelectionChangedEventArgs args)
        {
            if (args.SelectedItem is NavigationViewItem item && item.Tag is Type pageType)
            {
                contentFrame.Navigate(pageType);
            }
        }

CodePudding user response:

Try passing the Type like this:

[MarkupExtensionReturnType(ReturnType = typeof(Type))]
public sealed class TypeExtension : MarkupExtension
{
    public Type? Type { get; set; }

    protected override Type? ProvideValue()
    {
        return Type;
    }
}
<NavigationViewItem Content="Home" Tag="{l:Type Type=pages:HomePage}"/>

But there's an ongoing issue in WinUI 3 when you return Type with MarkupExtensions, so you'll have to wait until they fix it.

  • Related