tags:

views:

28

answers:

2

I want to dynamically construct a TreeView using Node which represents a typical tree node. The Node looks like

class Node
{
    public Node(string cont) {
        Content = cont;
        Children = new List<Node>();
    }

    public string Content { get; set; }
    public List<Node> Children { get; set; }
    public bool IsLeaf {
        get { return Children.Count == 0; }
    }
    public bool IsVisible {
        get { return true; }
    }
}

In order to that that I wrote the simple tree traversal which adds TreeViewItems

   void XmlTreeTraversal(DataPoolNode curNode, TreeViewItem curViewNode) {
        if (curNode.IsLeaf)
            return;

        var contentNode = (DataPoolNode)curNode;
        foreach (var node in contentNode.Children) {
            TreeViewItem childViewNode = AddNewNodeToTreeView(node.Content, curViewNode);

            XmlTreeTraversal(node, childViewNode);
        }
    }

    TreeViewItem AddNewNodeToTreeView(string description, TreeViewItem curViewNode) {
        TreeViewItem newTVI = new TreeViewItem();
        newTVI.Header = description;
        curViewNode.Items.Add(newTVI);
        return newTVI;
    }

The problem with the approach is that data and view are intertwined. So It doesn't meet MVVC. Perhaps, you know another solution for this issue?

A: 

Follow this post

http://www.codeproject.com/KB/WPF/TreeViewWithViewModel.aspx

Best post using MVVM for Tree Construction.

saurabh
A: 

Do not create the tree yourself. The TreeView-control is one of the conrols that strongly profits from DataBinding and even more from MVVM. Without, it can be a pain to work with. With DataBinding and MVVM, using TreeView is really easy:

You already have a good source for the TreeView. Its your Node-class. Set a list to the root-node as the ItemsSource of your TreeView...

m_treeView.ItemsSource=new List<Node>(){yourRootNode};

...Make a HierarchicalDatraTemplate for your nodes. Something like...

<HierarchicalDataTemplate x:Key="TreeViewItem_HierarchicalDataTemplate" ItemsSource="{Binding Children}" >
         <TextBlock Text="{Binding Content}"  />                
</HierarchicalDataTemplate>

...and set the ItemsTemplate of the TreeView accordingly...

<TreeView Name="m_treeView" ItemTemplate="{StaticResource TreeViewItem_HierarchicalDataTemplate}" .../>

If the Node-class is already the ViewModel, it can be interesting to also include an IsSelected and IsExpandend-property and the bind the ItemsContainerStyle-properies to this (do not forget about the INotifyPropertyChanged-event)..

<TreeView.ItemContainerStyle>                
    <Style TargetType="{x:Type TreeViewItem}">
        <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
        <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
    </Style>
</TreeView.ItemContainerStyle>

In the beginning it's a little more work but it can save you hours of time if you then want to do more complicated operations such as automatically selecting and expanding.

HCL