Description
Describe the bug
After updating TreeView.ItemsSource
property TreeViewNode(s)/TreeViewItem(s) are not updated properly. It seems like TreeView is reusing previously created TreeViewNode(s)/TreeViewItem(s) without properly resetting their state. Below you can find example showing problem with Style
and IsExpanded
properties of TreeViewItem
. The same will happen with HasUnrealizedChildren
property of TreeViewNode. The issue exists if you update ItemsSource
in code behind or using binding.
Steps to reproduce the bug
-
In VisualStudio 2022 (17.1.3) create new project -
Blank App, Packaged (WinUI 3 in Desktop)
. -
Add code to MainWindow.xaml file
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.Resources>
<DataTemplate x:Key="RedItemTemplate" x:DataType="local:RedItem">
<TreeViewItem Content="{Binding}" ItemsSource="{Binding Children}" IsExpanded="True" Foreground="Red"/>
</DataTemplate>
<DataTemplate x:Key="GreenItemTemplate" x:DataType="local:GreenItem">
<TreeViewItem Content="{Binding}" ItemsSource="{Binding Children}" IsExpanded="True" Foreground="Green"/>
</DataTemplate>
<local:ColorItemTemplateSelector
x:Key="ColorItemTemplateSelector"
RedItemTemplate="{StaticResource RedItemTemplate}"
GreenItemTemplate="{StaticResource GreenItemTemplate}">
</local:ColorItemTemplateSelector>
</Grid.Resources>
<CommandBar Grid.Row="0" DefaultLabelPosition="Right" VerticalContentAlignment="Center" FontWeight="Bold">
<AppBarButton Click="RedItems_Click" Label="Red items" />
<AppBarButton Click="GreenItems_Click" Label="Green items" />
<AppBarButton Click="Clear_Click" Label="Clear" />
</CommandBar>
<TreeView Grid.Row="1" x:Name="TreeView" ItemTemplateSelector="{StaticResource ColorItemTemplateSelector}" />
</Grid>
- Add code to MainWindow.xaml.cs file
public sealed partial class MainWindow : Window
{
private readonly List<ColorItem> RedItems = ColorItem.Create<RedItem>(3);
private readonly List<ColorItem> GreenItems = ColorItem.Create<GreenItem>(3);
public MainWindow() => InitializeComponent();
private void UpdateTreeView(List<ColorItem> items) => TreeView.ItemsSource = items;
private void RedItems_Click(object sender, RoutedEventArgs e) => UpdateTreeView(RedItems);
private void GreenItems_Click(object sender, RoutedEventArgs e) => UpdateTreeView(GreenItems);
private void Clear_Click(object sender, RoutedEventArgs e) => UpdateTreeView(null);
}
public class ColorItem
{
public List<ColorItem> Children { get; set; }
public override string ToString() => GetType().Name;
public static List<ColorItem> Create<T>(int childCount) where T : ColorItem, new()
{
var items = new List<ColorItem>();
for (int i = 1; i <= childCount; i++)
{
var item = new T();
item.Children = Create<T>(childCount - 1);
items.Add(item);
}
return items;
}
}
public class RedItem : ColorItem { }
public class GreenItem : ColorItem { }
public class ColorItemTemplateSelector : DataTemplateSelector
{
public DataTemplate RedItemTemplate { get; set; }
public DataTemplate GreenItemTemplate { get; set; }
protected override DataTemplate SelectTemplateCore(object item)
{
return item switch
{
RedItem => RedItemTemplate,
GreenItem => GreenItemTemplate,
_ => null
};
}
}
- Run the project
- Randomly click button
- Collapse some of the TreeView nodes
- Click randomly button again
- Note that styles are not updated according to clicked button (for example RedItems are displayed as green)
- Note that some of newly created nodes are Collapsed although the style is set make them expanded by default.
Expected behavior
After updating ItemsSource
property existing RootNodes
should be cleared and new nodes should be created for new items.
Screenshots
NuGet package version
WinUI 3 - Windows App SDK 1.0.3
Windows app type
- UWP
- Win32
Device form factor
Desktop
Windows version
Windows 10 (21H1): Build 19043
Additional context
Earlier I experienced strange behavior of SelectedItems
property. After changing ItemsSource
or even setting it to null
the SelectedItems
wasn't empty.