A better way to dynamically fill in the TreeView
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 TreeVie开发者_运维技巧wItem();
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?
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.
精彩评论