views:

137

answers:

3

Say I have a binary tree, where the root of the data structure is just a tree node. For each node, the children are accessible through the Children property. Here's what I tried. The TreeRoot is a property of the inherited data context, but it's a single node (not a collection).

<UserControl.Resources>
    <HierarchicalDataTemplate x:Key="TreeNodeTemplate" ItemsSource="{Binding Children}">
        <TextBlock Text="{Binding Name}" />
    </HierarchicalDataTemplate>
</UserControl.Resources>

<Grid>
    <TreeView ItemsSource="{Binding TreeRoot}" ItemTemplate="{StaticResource TreeNodeTemplate}" />
</Grid>
+1  A: 

I think your problem is that your hierarchical data template is only applied to the root node, so you never see anything past the root's children. Try this instead:

<UserControl.Resources>
    <HierarchicalDataTemplate DataType="{x:Type TreeNode}" ItemsSource="{Binding Children}">
        <TextBlock Text="{Binding Name}" />
    </HierarchicalDataTemplate>
</UserControl.Resources>

<Grid>
    <TreeView ItemsSource="{Binding TreeRoot}"/>
</Grid>

Where TreeNode is the name of your tree node class.

Aviad P.
A: 

Like Aviad said, if you use DataType="{x:Type TreeNode}" then the TreeView will automatically use that template for any object of that type.

If you have multiple types in your hierarchy, you can specify multiple HierarchicalDataTemplates each with the data type it's for. That would let the TreeView handle each type differently.

<HierarchicalDataTemplate DataType="{x:Type TreeNode}" ItemsSource="{Binding Children}">
    <TextBlock Text="{Binding Name}" />
</HierarchicalDataTemplate>

<HierarchicalDataTemplate DataType="{x:Type TreeLeaf}">
    <TextBlock Text="{Binding Message}" Background="Red" />
</HierarchicalDataTemplate>
Benny Jobigan
A: 

I had this problem and concluded that I couldn't bind a non-collection to a treeview as a way to specify the root node. So what I did was to make a quick change to my ModelView and make the property representing the root node a collection of 1 item.

public class ContainerViewModel
{
   public ObservableCollection<TreeNodeViewModel> RootNodes { get; private set; }

   public ContainerViewModel()
   {
      // Create a single node in the collection of root nodes
      RootNodes = new ObservableCollection<TreeNodeViewModel>();
      RootNodes.Add(new TreeNodeViewModel());
   }
}

public class TreeNodeViewModel
{
   public ObservableCollection<TreeNodeViewModel> Children { get; set; }
}

I used an ObservableCollection<> above but might make more sense to use something cheaper like a List<> since you don't expect the collection to change (at least in your scenario).

Canoehead