tags:

views:

86

answers:

2

I have a List that I've bound to a TreeView. Setting TreeView.DataContext works - everything displays correctly. I then change the list (add an item to it) and set TreeView.DataContext again (to the same value) but the tree does not refresh with the new items. How do I get the treeview to refresh?

This is basically my code:

public class xItemCollection : ObservableCollection<xItem>
{
}

public class xItem : INotifyPropertyChanged
{
    xItemCollection _Items;
    string m_Text;

    public xItem()
    {
        _Items = new xItemCollection();
    }

    public xItemCollection Items {get{return _Items;}}
    public string Text {get{return m_Text;} set{m_Text=value;}}
}

class MyProgram
{
    xItem m_RootItem;

    void UpdateTree()
    {
        this.RootItem = new xItem();
        treeView.DataContext = this;
    }

    public xItem RootItem
    {
        get { return m_RootItem;}
        set { m_RootItem = value;}
    }
}

The xaml is:

<TreeView Name="Tree" ItemsSource="{Binding Path=RootItem.Items}" >

<TreeView.ItemTemplate>
    <HierarchicalDataTemplate ItemsSource="{Binding Items}">
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="{Binding Text}" />
        </StackPanel>
    </HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>

Adding items to the list works until the tree is rendered for the first time. After it is rendered, adding/removing items does not refresh the tree.

+2  A: 

if you assign the same object to a datacontext, I guess it will not fire the datacontext as being changed.

you have some options here:

  1. assign null to the datacontext and reassign your list, or call any other "refreshing command" that gets your datacontext refreshed, which is actually a pretty bad idea as your whole tree has to be regenerated.

  2. use an ObservableCollection as your list. This automatically triggers a CollectionChanged event if you add an item, that WPF uses to update only the ChangedParts of the list.

I would definatly recommend using the second approach!

redoced
The first approach works. The second doesn't.With the second it is still not refreshing the tree. I've added my code to the question.
dan gibson
+1  A: 

I needed to implement INotifyPropertyChanged and then fire PropertyChanged when RootItem changed. My code was creating a new list of items then assigning the complete list to RootItem. Without PropertyChanged the TreeView never knew that RootItem had changed.

dan gibson
with the code set up as you stated you don't need the propertychanged on your rootitem. but instead of creating a new list and assigning that to the items property, Clear it and then do an AddRange
redoced