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