Home > Software engineering >  How to bind MetadataControl items to a collection in XAML with WINUI 3
How to bind MetadataControl items to a collection in XAML with WINUI 3

Time:07-07

I'm trying to use the MetadataControl from the windows community toolkit.

In the sample app, items are added programmatically and I can't find a way to bind to a class with a data template directly in Xaml.

I tried the following code but it won't work:

<controls:MetadataControl Items="{x:Bind myClass}">
    <ControlTemplate>
         <DataTemplate x:DataType="local:myClass">
            <.....>
         </DataTemplate>
     </ControlTemplate>
</controls:MetadataControl>

If anybody had a example of how to do bind it directly in XAML without having to populate items from code, it will we great.

Thank you

CodePudding user response:

MetadataItem is a struct and AFAIK you can't initialize a struct in XAML.

I also recommend that you create a collection of MetadataItems like it in the samples.

That said, I build up this code using an Attached Property and achieved what you are trying to do. The namings are verbose but I think I'd be easier to get what it represents in this case. I hope this helps.

MetadataControlExtension.cs

using CommunityToolkit.WinUI.UI.Controls;
using Microsoft.UI.Xaml;
using System.Collections.Generic;

namespace MetadataControlExtension;

public class MetadataControlExtensionItem
{
    public string Label { get; set; } = string.Empty;
}

public class MetadataControlExtensionItemList : List<MetadataControlExtensionItem>
{
}

public class MetadataControlExtension : DependencyObject
{
    public static IEnumerable<MetadataControlExtensionItem> GetItemsSource(DependencyObject obj)
    {
        return (IEnumerable<MetadataControlExtensionItem>)obj.GetValue(ItemsSourceProperty);
    }

    public static void SetItemsSource(DependencyObject obj, IEnumerable<MetadataControlExtensionItem> value)
    {
        obj.SetValue(ItemsSourceProperty, value);
    }

    public static readonly DependencyProperty ItemsSourceProperty =
        DependencyProperty.RegisterAttached(
            "ItemsSource",
            typeof(IEnumerable<MetadataControlExtensionItem>),
            typeof(MetadataControlExtension), new PropertyMetadata(0, OnItemsSourcePropertyChanged));

    private static void OnItemsSourcePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is MetadataControl metadataControl && e.NewValue is IEnumerable<MetadataControlExtensionItem> itemsSource)
        {
            List<MetadataItem> metadataItems = new();

            foreach (MetadataControlExtensionItem item in itemsSource)
            {
                metadataItems.Add(new MetadataItem() { Label = item.Label });
            }

            metadataControl.Items = metadataItems;
        }
    }
}

MainWindow.xaml

<Window
    x:Class="MetadataControlTest.MainWindow"
    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:controls="using:CommunityToolkit.WinUI.UI.Controls"
    xmlns:ex="using:MetadataControlExtension"
    mc:Ignorable="d">

    <Grid>
        <controls:MetadataControl>
            <ex:MetadataControlExtension.ItemsSource>
                <ex:MetadataControlExtensionItemList>
                    <ex:MetadataControlExtensionItem Label="1st Item"/>
                    <ex:MetadataControlExtensionItem Label="2nd Item"/>
                    <ex:MetadataControlExtensionItem Label="3rd Item"/>
                    <ex:MetadataControlExtensionItem Label="4th Item"/>
                    <ex:MetadataControlExtensionItem Label="5th Item"/>
                </ex:MetadataControlExtensionItemList>
            </ex:MetadataControlExtension.ItemsSource>
        </controls:MetadataControl>
    </Grid>

</Window>
  • Related