views:

523

answers:

2

I'm using a WPF TreeView control, which I've bound to a simple tree structure based on ObservableCollections. Here's the XAML:


<TreeView Name="tree" Grid.Row="0"> 
    <TreeView.ItemTemplate> 
        <HierarchicalDataTemplate ItemsSource="{Binding Path=Children}"> 
            <TextBlock Text="{Binding Path=Text}"/> 
        </HierarchicalDataTemplate> 
    </TreeView.ItemTemplate> 
</TreeView>  

And the tree structure:


public class Node : IEnumerable { 
    private string text; 
    private ObservableCollection<Node> children; 
    public string Text { get { return text; } } 
    public ObservableCollection<Node> Children { get { return children; } } 
    public Node(string text, params string[] items){ 
        this.text = text; 
        children = new ObservableCollection<Node>(); 
        foreach (string item in items) 
            children.Add(new Node(item)); 
    } 
    public IEnumerator GetEnumerator() { 
        for (int i = 0; i < children.Count; i++) 
            yield return children[i]; 
    } 
} 

I set the ItemsSource of this tree to be the root of my tree structure, and the children of that become root-level items in the tree (just as I want):


private Node root; 

root = new Node("Animals"); 
for(int i=0;i<3;i++) 
    root.Children.Add(new Node("Mammals", "Dogs", "Bears")); 
tree.ItemsSource = root; 

I can add new children to the various non-root nodes of my tree structure, and they appear in the TreeView right where they should.

root.Children[0].Children.Add(new Node("Cats", "Lions", "Tigers"));  

But, if I add a child to the root node:

root.Children.Add(new Node("Lizards", "Skinks", "Geckos")); 

The item does not appear, and nothing I've tried (such as setting the ItemsSource to null and then back again) has caused it to appear.

If I add the lizards before setting the ItemsSource, they show up, but not if I add them afterwards.

The cats appear, but not the lizards

Any ideas?

+1  A: 

if 'root' is an ObservableCollection your treeview will update. is 'root' an observable collection, or is root a node that is in an observable collection? seeing your binding for the items source would help to answer this question. as you are assigning it in code you might just be setting it to be a single element, not a collection

Aran Mulholland
I've updated the question with the relevant details - "root" is just a Node like all the others. It doesn't show up in the TreeView itself, but that's fine. If I create a observable NodeCollection and use that as the root, it doesn't make any difference.
Jivlain
+2  A: 

You are setting ItemsSource = root which happens to implement IEnumerable but is not in and of itself observable. Even though you have a Children property which is observable, that's not what you're binding the TreeView to so the TreeView doesn't have any way of listening to changes that occur through the Children property.

I would drop IEnumerable from the Node class altogether. Then set treeView.ItemsSource = root.Children;

Josh Einstein