views:

203

answers:

3

I am trying to bind some data from a class instance to a TreeView. My code is as follows:

public partial class MainWindow : Window
{        
    public MainWindow()
    {
        InitializeComponent();

        Parent myClass = new Parent();
        this.DataContext = myClass;
    }
}

public class Parent
{
    private List<string> children = new List<string>;

    public string Name {get;set;}
    public List<string> Children 
    {
        get { return this.children; } 
        set { this.children=value; }
    }

    public Parent()
    {
        this.Name = "Test";

        for (int i = 1; i <= 10; i++)
        {
            Children.Add(i.ToString());
        }
    }
}

And the XAML:

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:loc="clr-namespace:WpfApplication1"
    Title="MainWindow" Height="287" Width="525">

    <StackPanel Orientation="Horizontal" VerticalAlignment="Stretch">
        <TreeView Name="TreeView" ItemsSource="{Binding}">
            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate ItemsSource="{Binding Children}">
                        <TextBlock Text="{Binding Name}"/>
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>
    </StackPanel>    
</Window>

Nothing shows up in my TreeView. What am I doing wrong?

I expect to see:

-Test
-- 1
-- 2
-- 3
etc

updated: to make Name and Children properties instead of public fields.
updated: added what I expect to see in TreeView

A: 

You can only bind to public properties, not fields. Change Name and Children to be public properties and this should work.

Charlie
Made this update (shown in original question) and nothing changed. TreeView is still empty.
KrisTrip
+1  A: 

You bind "myClass" of type Parent to the datacontext and use the same object for the ItemSource. This won't work because Parent is not an enumerable type.

Change your ItemSource binding from "{Binding}" to "{Binding Children}" and change your HierarchicalDataTemplate to just a DataTemplate.

If you want to retain myClass as a top level node, you could also wrap myclass in an IEnumerable and set that as the data context.

apandit
In this case, how would I get the Parent.Name to show up as the top level node?This is what I want to see:-Test--1--2--3--4etc
KrisTrip
Create a list of type Parent and add myclass to it. Then, set the datacontext to the list instead of the object.
apandit
A: 

Here try this:

   <StackPanel Orientation="Horizontal" VerticalAlignment="Stretch">
        <TextBlock Text="{Binding Name}"/>
        <TreeView Name="TreeView" ItemsSource="{Binding Children}">
            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate ItemsSource="{Binding Children}">
                    <TextBlock Text="{Binding}"/>
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>
        </TreeView>
    </StackPanel>

A few things:

  • The 'Name' Property was out of scope.
  • We need to bind the TreeView as well as the DataTemplate
  • We use the default {Binding} to call ToString() on the current item.
VoidDweller