WPF TreeView bound to ObservableCollection not updating root nodes

Tim Coulter picture Tim Coulter · Jan 26, 2010 · Viewed 15.6k times · Source

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

Answer

Sam Harwell picture Sam Harwell · Jan 26, 2010

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;
    }
}