0

I have a WinUI 3 project scaffolded using Template Studio. I have a list view populated with an Enum. I want to show my selected items in another list, but the binding does not work.
Populated with Enum meaning I take <key, value> pairs with enum value and enum description and use as ItemsSource. Selection Mode Multiple active.

public IEnumerable<KeyValuePair<string, string>> ValidationFlagsList => EnumExtensions.GetAllValuesAndDescriptions<ValidationFlag>();

//...
public static IEnumerable<KeyValuePair<string, string>> GetAllValuesAndDescriptions<TEnum>() where TEnum : struct, IConvertible, IComparable, IFormattable
{
    return typeof(TEnum).IsEnum ? (from e in Enum.GetValues(typeof(TEnum)).Cast<Enum>() select new KeyValuePair<string, string>(e.ToString(), e.GetDescription())) : throw new ArgumentException("TEnum must be an Enumeration type");
}
<ListView
        x:Name="FlagsListView"
        SelectionMode="Multiple"
        ItemsSource="{x:Bind ViewModel.ValidationFlagsList, Mode=OneTime}"
        SelectedValuePath="Key"
        DisplayMemberPath="Value">
</ListView>

In another part of xaml I want to show the selected items. I tried two variants:

1.

<ListView ItemsSource="{Binding SelectedItems, ElementName=FlagsListView, Mode=OneWay}"/>

2.

<StackPanel DataContext="{Binding SelectedItems, ElementName=FlagsListView}">
    <TextBlock Text="{Binding}"/>
</StackPanel>

Nothing shows on UI. How can I bind correctly?

Is it because IEnumerable is static and ObservableCollection is needed? But the xaml ListView should give me some straightforward binding. Documentation points to this Data binding. I read about creating a class with IsSelected property, but I only need a readonly list, preferably to add something only in xaml.

1 Answer 1

1

The ListView does have a SelectedItems property but it's just a plain property and not a DependencyProperty. Unfortunately you can't use it with bindings.

What you can do is create a custom ListView:

ListViewEx.cs

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

namespace ListViews;

public class ListViewEx : ListView
{
    public ListViewEx() : base()
    {
        this.SelectionChanged += ListViewEx_SelectionChanged;
    }

    public new IList SelectedItems
    {
        get => (IList)GetValue(SelectedItemsProperty);
        set => SetValue(SelectedItemsProperty, value);
    }

    public static readonly DependencyProperty SelectedItemsProperty = DependencyProperty.Register(
        nameof(SelectedItems),
        typeof(IList),
        typeof(ListViewEx),
        new PropertyMetadata(new ObservableCollection<object>()));

    private void ListViewEx_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        foreach (object item in e.RemovedItems)
        {
            SelectedItems.Remove(item);
        }

        foreach (object item in e.AddedItems)
        {
            SelectedItems.Add(item);
        }
    }
}

and use it like this:


<Grid ColumnDefinitions="*,*">
    <local:ListViewEx
        x:Name="FlagsListView"
        Grid.Column="0"
        DisplayMemberPath="Value"
        ItemsSource="{x:Bind ViewModel.ValidationFlagsList, Mode=OneTime}"
        SelectedValuePath="Key"
        SelectionMode="Multiple" />

    <ListView
        Grid.Column="1"
        ItemsSource="{x:Bind FlagsListView.SelectedItems, Mode=OneWay}" />
</Grid>
Sign up to request clarification or add additional context in comments.

2 Comments

Can you suggest also a folder where I should keep these custom xaml? Views, ViewModels folder or another?
If you don't have a bunch of custom controls, and you have a Views folder, I'd just put in there. Or create a Controls folder inside the Views folder or at the same level with it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.