0

I am trying to generate a tree view dynamically in WinUI3 desktop application. It can generate the tree but all nodes are unselected by default. My application need to remember selection and replicate previous status.

Technically I am able to read selection status from TreeView.SelectedNodes. However I am not able to find the way to select an node from the code.

I found couple of related articles for WPF or UWP on the net, but not for WinUI3.

Environment

  • WinUI3 desktop
  • Windows App SDK 1.0.0
  • MvvmGen 1.1.2

Goal

  • Select some items in the tree at start up.
  • Read status of selection from a ViewModel.

Problem

  • Unable to bind IsSelected property in a view to ListViewItem.IsSelected.

Code

MainWindow.xaml

<Window
    x:Class="WinUITreeViewTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:WinUITreeViewTest"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d">

    <StackPanel DataContext="MainWindowViewModel">
        <TreeView Name="MyItemView" SelectionMode="Multiple" ItemsSource="{Binding MyItems}">
            <TreeView.ItemTemplate>
                <DataTemplate x:DataType="local:MyItem">
                    <TreeViewItem ItemsSource="{Binding Children}" Content="{Binding Name}" IsExpanded="{Binding IsExpanded}" IsSelected="{Binding IsSelected}"/>
                </DataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>
    </StackPanel>
</Window>

In the TreeViewItem node, it is intended to bind MyItem.IsSelected to TreeViewItem.IsSelcted. Is does not work.

MainWindow.xaml.cs

public sealed partial class MainWindow : Window
{
    public MainWindow()
    {
        this.InitializeComponent();

        ViewModel = new MainWindowViewModel();
        MyItemView.DataContext = ViewModel;

        ObservableCollection<MyItem> root = new ObservableCollection<MyItem>();

        MyItem item1 = new MyItem() { Name = "Item1", IsExpanded=true };
        root.Add(item1);
        item1.Children.Add(new MyItem() { Name = "Item1.1" });
        item1.Children.Add(new MyItem() { Name = "Item1.2" });
        item1.Children.Add(new MyItem() { Name = "Item1.3", IsSelected=true });

        MyItem item2 = new MyItem() { Name = "Item2", IsExpanded = true };
        root.Add(item2);
        item2.Children.Add(new MyItem() { Name = "Item2.1" });
        item2.Children.Add(new MyItem() { Name = "Item2.2" });
        item2.Children.Add(new MyItem() { Name = "Item2.3" });

        MyItem item3 = new MyItem() { Name = "Item3", IsExpanded = true };
        root.Add(item3);
        item3.Children.Add(new MyItem() { Name = "Item3.1" });
        item3.Children.Add(new MyItem() { Name = "Item3.2" });
        item3.Children.Add(new MyItem() { Name = "Item3.3" });

        ViewModel.MyItems = root;
    }

    MainWindowViewModel ViewModel;
}
MainWindowViewModel.cs

[ViewModel]
public partial class MainWindowViewModel
{
    [Property]
    ObservableCollection<MyItem> myItems;
}

[ViewModel]
public partial class MyItem
{
    [Property]
    private string name;

    public override string ToString() => Name;

    [Property]
    private bool? isSelected;

    [Property]
    private bool isExpanded;

    [Property]
    private ObservableCollection<MyItem> children = new ObservableCollection<MyItem>();
}

MvvmGen generates corresponding property for MVVM automatically like this.

public bool? IsSelected
{
    get => isSelected;
    set
    {
        if (isSelected != value)
        {
            isSelected = value;
            OnPropertyChanged("IsSelected");
        }
    }
}

Reference : https://github.com/hayashida-katsutoshi/WinUITreeViewTest

1 Answers1

0

This was a known issue. I found a ticket in GitHub.

https://github.com/microsoft/microsoft-ui-xaml/issues/125