xamlwinui-3winuiwindows-app-sdkwinui-xaml

How to set the SelectedItem for the ItemsView control in WinUI 3?


The ItemsView's SelectedItem Property is a readonly property so it doesn't support two way binding. You can find the reference here

https://learn.microsoft.com/en-us/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.controls.itemsview.selecteditem?view=windows-app-sdk-1.7

When clicking on an item in the ItemsView, the selection indication is showing in WinUI3 Gallery app. But when arrow keys are used to navigate the selection is unselecting. enter image description here

Is there any workaround for this ?


Solution

  • Try the following custom control. It inherits from ItemsView and replaces the original SelectedItem with its own version using the new modifier. It seems to be working fine on my end.

    public partial class ItemsViewEx : ItemsView
    {
        public static new readonly DependencyProperty SelectedItemProperty =
            DependencyProperty.Register(
                nameof(SelectedItem),
                typeof(object),
                typeof(ItemsViewEx),
                new PropertyMetadata(default, OnSelectedItemPropertyChanged));
    
        public ItemsViewEx()
        {
            SelectionChanged += ItemsViewEx_SelectionChanged;
        }
    
        public new object SelectedItem
        {
            get => (object)GetValue(SelectedItemProperty);
            set => SetValue(SelectedItemProperty, value);
        }
    
        private static void OnSelectedItemPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is not ItemsViewEx itemsViewEx ||
                itemsViewEx.ItemsSource is not IList items)
            {
                return;
            }
    
            int index = items.IndexOf(e.NewValue);
    
            if (index < 0 || index >= items.Count)
            {
                return;
            }
    
            itemsViewEx.Select(index);
        }
    
        private void ItemsViewEx_SelectionChanged(ItemsView sender, ItemsViewSelectionChangedEventArgs args)
        {
            SelectedItem = sender.SelectedItem;
        }
    }