Skip to content

TreeView does not clear nodes state after updating ItemsSource  #7044

Open

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

  1. In VisualStudio 2022 (17.1.3) create new project - Blank App, Packaged (WinUI 3 in Desktop) .

  2. 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>
  1. 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
            };
        }
    }
  1. Run the project
  2. Randomly click button
  3. Collapse some of the TreeView nodes
  4. Click randomly button again
  5. Note that styles are not updated according to clicked button (for example RedItems are displayed as green)
  6. 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

winui3-treeview-v2

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions