Databinding WPF treeview using recursion

15 Lug

Today I solved a very interesting problem using a TreeView and a HierarchicalDataTemplate. My final goal was to display an objects tree using a TreeView control as shown here below.

image

The result is not very nice but wait, I am a developer not a designer!
Ok, less chatter! Let’s look at the code that is much more interesting.
In this case the datasource is a tree composed by a set of Foo objects.
Here is the Foo class definition

public class Foo
{
    public Foo()
    {
        Children = new List<Foo>();
    }
    public int Id { get; set; }
    public string Name { get; set; }
    public IList<Foo> Children { get; set; }
}

and here a dummy method that create a sample objects tree

public class Service
{
    private readonly Collection<Foo> fooList;

    public IEnumerable<Foo> FooList
    {
        get { return fooList; }
    }

    public Service()
    {
        fooList = new Collection<Foo> { new Foo { Id = 0, Name = "first" }, new Foo { Id = 99, Name = "makka" } };
        fooList[0].Children.Add(new Foo { Id = 1, Name = "second" });
        fooList[0].Children.Add(new Foo { Id = 2, Name = "third" });
        fooList[0].Children[0].Children.Add(new Foo { Id = 3, Name = "fourth" });
    }
}

Until here nothing special.
The interesting part is the XAML markup. As you can see using the power of HierarchicalDataTemplate with few lines of code we can create a recursive loop in order to populate the TreeView starting from a simple IEnumerable<Foo> object

<TreeView Name="viewsTreeView"  >
    <TreeView.Resources>
        <HierarchicalDataTemplate DataType="{x:Type Demo:Foo}" ItemsSource="{Binding Path=Children}">
            <TreeViewItem Header="{Binding Path=Name}"  />
        </HierarchicalDataTemplate>
    </TreeView.Resources>
</TreeView>

I hope this sample will save you some time!

7 Risposte to “Databinding WPF treeview using recursion”

  1. zuraff giugno 17, 2009 a 7:53 pm #

    Hi,
    can you explain how do you tell your instance of TreeView (viewsTreeView) that you want instances of Foo class to be taken from Service class ?

    Also notation: ‘Demo:Foo’ in <HierarchicalDataTemplate DataType="{x:Type Demo:Foo}"… is not exactly clear. I guess Demo is a namespace of Foo, what is not noted in the snippet of Foo.

    Thanks in advance

    Zuraff

  2. Bob Bedell agosto 29, 2009 a 5:55 pm #

    Hi Zuraff,

    Here’s some more complete markup:

  3. Bob Bedell agosto 29, 2009 a 6:12 pm #

    OK, let me try escaping angle brackets…

    
     &ltWindow x:Class="Default.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:src="clr-namespace:Default"    
        Title="Window1" Height="300" Width="300"&gt
        &ltWindow.Resources>
            &ltsrc:DataService x:Key="dataSource" /&gt
            &ltHierarchicalDataTemplate x:Key="itemTemplate" 
                                      DataType="{x:Type src:Foo}" 
                                      ItemsSource="{Binding Path=Children}"&gt
                &ltTreeViewItem Header="{Binding Path=Name}"  /&gt
            &lt/HierarchicalDataTemplate&gt
        &lt/Window.Resources>
        &ltTreeView ItemsSource="{Binding Source={StaticResource dataSource}, Path=FooList}"
                  ItemTemplate="{StaticResource itemTemplate}" /&gt
    &lt/Window&gt
    
    
  4. Bob Bedell agosto 29, 2009 a 6:14 pm #

    hmm…better…without

     tags???
    
    
     &ltWindow x:Class="Default.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:src="clr-namespace:Default"    
        Title="Window1" Height="300" Width="300"&gt
        &ltWindow.Resources>
            &ltsrc:DataService x:Key="dataSource" /&gt
            &ltHierarchicalDataTemplate x:Key="itemTemplate" 
                                      DataType="{x:Type src:Foo}" 
                                      ItemsSource="{Binding Path=Children}"&gt
                &ltTreeViewItem Header="{Binding Path=Name}"  /&gt
            &lt/HierarchicalDataTemplate&gt
        &lt/Window.Resources>
        &ltTreeView ItemsSource="{Binding Source={StaticResource dataSource}, Path=FooList}"
                  ItemTemplate="{StaticResource itemTemplate}" /&gt
    &lt/Window&gt
  5. Bob Bedell agosto 29, 2009 a 6:15 pm #

    oh well, you get the idea…

  6. Murugan Andezuthu Dharmaratnam agosto 30, 2009 a 1:21 pm #

    Here’s the sample code

    Dim oDataSet As New DataSet
    Public Sub PopulateTree(ByVal ParentId As String, ByVal TVNode As TreeNode)
    Dim oDataView As New DataView(oDataSet.Tables(0), “ParentID='” & ParentId & “‘”,
    “DATA”, DataViewRowState.OriginalRows)
    Dim oDataRow As DataRowView
    For Each oDataRow In oDataView
    Dim oTreeNode As New TreeNode(oDataRow(“DATA”))
    Dim oComboBox As New ComboBox
    If TVNode Is Nothing Then
    Else
    TVNode.Nodes.Add(oTreeNode)
    PopulateTree(oDataRow(“ID”), oTreeNode)
    End If
    Next
    End Sub

    Read In Details http://muruganad.com/ASP.NET/ASP_.NET_How_to_Populate_a_TreeView_Control_With_TreeNode_s_Using_recursive_algorithm_or_recursion_.html

    Thanks

    Murugan Andezuthu Dharmaratnam

  7. Robert Compton ottobre 6, 2010 a 8:57 am #

    Thanks for the article mate!

Lascia un commento

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...

%d blogger cliccano Mi Piace per questo: