WPF TreeView bound to ObservableCollection not updating root nodes

16,321

Solution 1

My initial guess is that you have something like the following for the root node:

public ObservableCollection<Entity> Entities
{
    get;
    set;
}

Then, instead of doing something [good] like the following:

Entities.Clear();
foreach (var item in someSetOfItems)
    Entities.Add(item);

You are doing something [bad] like this:

Entities = new ObservableCollection<Entity>(someSetOfItems);

You should be able to track down the issue by making the backing field of the Entities property readonly:

private readonly ObservableCollection<Entity> _entities
    = new ObservableCollection<Entity>();

public ObservableCollection<Entity> Entities
{
    get
    {
        return _entities;
    }
}

Solution 2

Further explanation, long time for answer to come, but I believe that if you do the binding in XAML, and then in code assign a new object to the property you break the binding, so you would have to redo the binding in code for it to work. Hence the solution with the readonly backing field. If doing like that you will not be able to assign a new ObservableCollection and you won't break the binding by assigning a new object to the backing field.

Share:
16,321
Tim Coulter
Author by

Tim Coulter

I have spent my entire working life in the IT industry, working both as a technologist and as a manager. I have served in freelance and salaried roles and my responsibilities have ranged from software design and development to project management and consulting. Despite my technical bias, I recognize that technology exists only to serve commercial objectives. It is this dual capacity of technologist and entrepreneur that continues to drive my ambitions in new and exciting directions. After a number of years on the corporate career ladder, I have now exchanged my executive office for a work-at-home lifestyle, delivering Xamarin mobile consulting and software development services to a diverse group of corporate clients. Specialties: Xamarin, Microsoft .NET framework, C#

Updated on June 05, 2022

Comments

  • Tim Coulter
    Tim Coulter about 2 years

    Sorry - my question is almost identical to this one but since it didn't receive a viable answer, I am hoping that someone else has some fresh ideas.

    I have a WPF TreeView that is bound to a hierarchy of a single type:

    public class Entity
    {
        public string Title { get; set; }
        public ObservableCollection<Entity> Children { get; set; }
    }
    

    The Entity class implements INotifyPropertyChanged, but I have omitted this code for clarity.

    The TreeView is bound to an ObservableCollection<Entity> and each Entity instance exposes a set of contained Entity instances via its Children property:

    <TreeView ItemsSource="{Binding Path=Entities}">
        <TreeView.Resources>
            <HierarchicalDataTemplate DataType="{x:Type local:Entity}" ItemsSource="{Binding Path=Children}">
               <TextBlock Text="{Binding Path=Title}" />
            </HierarchicalDataTemplate>
       </TreeView.Resources>
    </TreeView>
    

    Initially the TreeView binds as expected and correctly displays a multi-level hierarchy. Also, when the membership of one of the Children collections is programmatically modified, the changes are correctly reflected in the TreeView.

    However, changes to the membership of the root member level ObservableCollection<Entity> are not reflected in the TreeView.

    Any suggestions would be appreciated.

    Thanks, Tim

  • Ingó Vals
    Ingó Vals about 12 years
    @Mike In the [Bad] example he is creating a new entity, thus breaking the binding to the original. In the [good] example he is just clearing and adding items to it but keeping the original collection.
  • riciloma
    riciloma over 6 years
    Excellent example, helped me with my Directory Tree TreeView