# Bind to Hierarchical Data Structure | WPF Controls | DevExpress Documentation

A hierarchical data structure is a set of nested objects where a ***children*** field contains child records. Parents and children can be of different object types.

The [DataControlBase.ItemsSource](/WPF/DevExpress.Xpf.Grid.DataControlBase.ItemsSource) property contains only data items that correspond to [root nodes](/WPF/9615/controls-and-libraries/data-grid/grid-view-data-layout/nodes/nodes-overview). Use the following techniques to make the [TreeListView](/WPF/DevExpress.Xpf.Grid.TreeListView) work with the hierarchical data structure:

- Child Nodes Path - Set a path to the ***children*** field. Use this technique only when child and parent fields have the same object type.
- Child Nodes Selector - Create a selector that returns node children. You can use this technique for different object types.
- Asynchronous Child Nodes Selector - Fetch child nodes in a background thread to keep the [TreeListView](/WPF/DevExpress.Xpf.Grid.TreeListView) responsive to user actions.
- Hierarchical Data Templates - Create a template for different data types.

## Child Nodes Path

[View Example: Implement the Child Nodes Path](https://github.com/DevExpress-Examples/wpf-treelist-implement-childnodespath)

Use the Child Nodes Path to bind the [TreeListView](/WPF/DevExpress.Xpf.Grid.TreeListView) to a collection if all objects have the same ***children*** field. An example of such a structure is shown below:

- C#
- VB.NET

<section id="tabpanel_DIm0Hz1q2O_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code class="lang-csharp">public class BaseObject {
    public string Name { get; set; }
    public String Executor { get; set; }
    public ObservableCollection&lt;Task&gt; Tasks { get; set; }
}

public class ProjectObject : BaseObject {}

public class Task : BaseObject {
    public string State { get; set; }
}
</code></pre></section>
<section id="tabpanel_DIm0Hz1q2O_tabid-vb" role="tabpanel" data-tab="tabid-vb" aria-hidden="true" hidden="hidden">
<pre><code class="lang-vb">Public Class BaseObject
    Public Property Name As String
    Public Property Executor As String
    Public Property Tasks As ObservableCollection(Of Task)
End Class

Public Class ProjectObject
    Inherits BaseObject
End Class

Public Class Task
    Inherits BaseObject

    Public Property State As String
End Class 
</code></pre></section>

1. Set the [TreeListView.ChildNodesPath](/WPF/DevExpress.Xpf.Grid.TreeListView.ChildNodesPath) property to the ***children*** field name.
2. Set the [TreeListView.TreeDerivationMode](/WPF/DevExpress.Xpf.Grid.TreeListView.TreeDerivationMode) property to **ChildNodesSelector**. 

     In the code sample below, the **Tasks** field is the ***children*** field:

- XAML

<section id="tabpanel_DIm0Hz1q2O-1_tabid-xaml" role="tabpanel" data-tab="tabid-xaml">
<pre><code class="lang-xaml">&lt;dxg:TreeListControl Name=&quot;treeListView1&quot; ItemsSource=&quot;{Binding DataItems}&quot;&gt;
    &lt;dxg:TreeListControl.Columns&gt;
        &lt;dxg:TreeListColumn FieldName=&quot;Name&quot; AllowSorting=&quot;True&quot; /&gt;
        &lt;dxg:TreeListColumn FieldName=&quot;Executor&quot; AllowSorting=&quot;True&quot; /&gt;
        &lt;dxg:TreeListColumn FieldName=&quot;State&quot; AllowSorting=&quot;True&quot; /&gt;
    &lt;/dxg:TreeListControl.Columns&gt;
    &lt;dxg:TreeListControl.View&gt;
        &lt;dxg:TreeListView TreeDerivationMode=&quot;ChildNodesSelector&quot; ChildNodesPath=&quot;Tasks&quot;/&gt;
    &lt;/dxg:TreeListControl.View&gt; 
&lt;/dxg:TreeListControl&gt;
</code></pre></section>

![](/WPF/images/child-nodes-path-approach.png)

Set the [TreeListView.AllowChildNodeSourceUpdates](/WPF/DevExpress.Xpf.Grid.TreeListView.AllowChildNodeSourceUpdates) property to **true** to update child nodes when you set the collection property to a new value.

## Child Nodes Selector

[Run Demo: Child Nodes Selector](dxdemo://Wpf/DXTreeList/MainDemo/BuildTreeViaChildNodesSelector) [View Example: Use the Child Nodes Selector to Display Hierarchical Data](https://github.com/DevExpress-Examples/wpf-treelist-use-child-nodes-selector-to-display-hierarchical-data)

Use the Child Nodes Selector to create a hierarchical data structure in the [TreeListView](/WPF/DevExpress.Xpf.Grid.TreeListView). An example of this structure is shown below:

- C#
- VB.NET

<section id="tabpanel_DIm0Hz1q2O-2_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code class="lang-csharp">public class ProjectObject : BaseObject {
    public ObservableCollection&lt;ProjectStage&gt; Stages { get; set; }
}

public class ProjectStage : BaseObject {
    public ObservableCollection&lt;Task&gt; Tasks { get; set; }
}

public class Task : BaseObject {
    State state;
    // ...
}
</code></pre></section>
<section id="tabpanel_DIm0Hz1q2O-2_tabid-vb" role="tabpanel" data-tab="tabid-vb" aria-hidden="true" hidden="hidden">
<pre><code class="lang-vb">Public Class ProjectObject
    Inherits BaseObject

    Public Property Stages As ObservableCollection(Of ProjectStage)
End Class

Public Class ProjectStage
    Inherits BaseObject

    Public Property Tasks As ObservableCollection(Of Task)
End Class

Public Class Task
    Inherits BaseObject

    Private state As State
    &#39; ...
End Class 
</code></pre></section>

1. Create a selector class that implements [IChildNodesSelector](/WPF/DevExpress.Xpf.Grid.IChildNodesSelector), and override the [SelectChildren(Object)](/WPF/DevExpress.Xpf.Grid.IChildNodesSelector.SelectChildren%28System.Object%29) method that returns node children.

     For the *Project-Stage-Task* class structure, the selector class is as follows:

- C#
    - VB.NET

<section id="tabpanel_DIm0Hz1q2O-3_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code class="lang-csharp">public class CustomChildrenSelector : IChildNodesSelector {
    public IEnumerable SelectChildren(object item) {
        if (item is ProjectStage)
            return ((ProjectStage)item).Tasks;
        else if (item is ProjectObject)
            return ((ProjectObject)item).Stages;
        return null;
    }
}
</code></pre></section>
<section id="tabpanel_DIm0Hz1q2O-3_tabid-vb" role="tabpanel" data-tab="tabid-vb" aria-hidden="true" hidden="hidden">
<pre><code class="lang-vb">Public Class CustomChildrenSelector
    Implements IChildNodesSelector

    Public Function SelectChildren(ByVal item As Object) As IEnumerable Implements IChildNodesSelector.SelectChildren
        If TypeOf item Is ProjectStage Then
            Return TryCast(item, ProjectStage).Tasks
        ElseIf TypeOf item Is ProjectObject Then
            Return TryCast(item, ProjectObject).Stages
        End If

        Return Nothing
    End Function
End Class
</code></pre></section>
2. Assign the Child Nodes Selector to the [TreeListView.ChildNodesSelector](/WPF/DevExpress.Xpf.Grid.TreeListView.ChildNodesSelector) property.
3. Set the [TreeListView.TreeDerivationMode](/WPF/DevExpress.Xpf.Grid.TreeListView.TreeDerivationMode) property to **ChildNodesSelector**.

- XAML

<section id="tabpanel_DIm0Hz1q2O-4_tabid-xaml" role="tabpanel" data-tab="tabid-xaml">
<pre><code class="lang-xaml">&lt;dxg:TreeListControl ...&gt;
    &lt;dxg:TreeListControl.Resources&gt;
        &lt;local:CustomChildrenSelector x:Key=&quot;childrenSelector&quot;/&gt;
    &lt;/dxg:TreeListControl.Resources&gt;
    &lt;dxg:TreeListControl.View&gt;
        &lt;dxg:TreeListView TreeDerivationMode=&quot;ChildNodesSelector&quot;
                          ChildNodesSelector=&quot;{StaticResource childrenSelector}&quot;/&gt;
    &lt;/dxg:TreeListControl.View&gt;
&lt;/dxg:TreeListControl&gt;
</code></pre></section>

Tip

If all objects have the same ***children*** field, assign its name to the [TreeListView.ChildNodesPath](/WPF/DevExpress.Xpf.Grid.TreeListView.ChildNodesPath) property. Otherwise, create a Child Nodes Selector.

## Fetch Nodes Asynchronously

[Run Demo: Asynchronous Data Loading](dxdemo://Wpf/DXTreeList/MainDemo/DynamicNodeLoading) [View Example: Load Nodes Asynchronously Without Locking the Application's UI](https://github.com/DevExpress-Examples/wpf-treelist-load-nodes-asynchronously)

If your Child Nodes Selector returns a large number of nodes, the fetch operation could freeze the application. To avoid this, create an **Asynchronous Child Nodes Selector** and fetch child nodes in a background thread. During fetch operations, parent nodes display loading indicators and the [TreeListView](/WPF/DevExpress.Xpf.Grid.TreeListView) remains responsive to user actions.

![TreeListView - Async Loading](/WPF/images/TreeListView_Async_Loading.gif)

1. Create a selector that implements the [IAsyncChildNodesSelector](/WPF/DevExpress.Xpf.Grid.IAsyncChildNodesSelector) interface and override the [HasChildNode](/WPF/DevExpress.Xpf.Grid.IAsyncChildNodesSelector.HasChildNode%28System.Object-System.Threading.CancellationToken%29) and [SelectChildrenAsync](/WPF/DevExpress.Xpf.Grid.IAsyncChildNodesSelector.SelectChildrenAsync%28System.Object-System.Threading.CancellationToken%29) methods:

- C#
    - VB.NET

<section id="tabpanel_DIm0Hz1q2O-5_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code class="lang-csharp">public class CustomChildrenSelector : IAsyncChildNodesSelector {
    public Task&lt;bool&gt; HasChildNode(object item, CancellationToken token) {
        return Task.Run(async () =&gt; {
            await Task.Delay(250);
            return !(item is StageTask);
        });
    }
    public IEnumerable SelectChildren(object item) {
        throw new NotImplementedException();
    }
    public Task&lt;IEnumerable&gt; SelectChildrenAsync(object item, CancellationToken token) {
        return Task.Run(async () =&gt; {
            await Task.Delay(1000);
            return SelectChildNodes(item);
        });
    }
    public IEnumerable SelectChildNodes(object item) {
        if (item is ProjectStage)
            return (item as ProjectStage).StageTasks;
        else if (item is ProjectObject)
            return (item as ProjectObject).ProjectStages;
        return null;
    }
}
</code></pre></section>
<section id="tabpanel_DIm0Hz1q2O-5_tabid-vb" role="tabpanel" data-tab="tabid-vb" aria-hidden="true" hidden="hidden">
<pre><code class="lang-vb">Public Class CustomChildrenSelector
    Implements IAsyncChildNodesSelector

    Public Function HasChildNode(ByVal item As Object, ByVal token As CancellationToken) As Task(Of Boolean) Implements IAsyncChildNodesSelector.HasChildNode
        Return Task.Run(Async Function()
            Await Task.Delay(250)
            Return Not(TypeOf item Is StageTask)
        End Function)
    End Function

    Public Function SelectChildren(ByVal item As Object) As IEnumerable Implements IChildNodesSelector.SelectChildren
        Throw New NotImplementedException()
    End Function

    Public Function SelectChildrenAsync(ByVal item As Object, ByVal token As CancellationToken) As Task(Of IEnumerable) Implements IAsyncChildNodesSelector.SelectChildrenAsync
        Return Task.Run(Async Function()
            Await Task.Delay(1000)
            Return SelectChildNodes(item)
        End Function)
    End Function

    Public Function SelectChildNodes(ByVal item As Object) As IEnumerable
        If TypeOf item Is ProjectStage Then
            Return TryCast(item, ProjectStage).StageTasks
        ElseIf TypeOf item Is ProjectObject Then
            Return TryCast(item, ProjectObject).ProjectStages
        End If
        Return Nothing
    End Function
End Class
</code></pre></section>
2. Assign the Child Nodes Selector to the [TreeListView.ChildNodesSelector](/WPF/DevExpress.Xpf.Grid.TreeListView.ChildNodesSelector) property.
3. Set the [TreeListView.TreeDerivationMode](/WPF/DevExpress.Xpf.Grid.TreeListView.TreeDerivationMode) property to `ChildNodesSelector`.

- XAML

<section id="tabpanel_DIm0Hz1q2O-6_tabid-xaml" role="tabpanel" data-tab="tabid-xaml">
<pre><code class="lang-xaml">&lt;dxg:TreeListControl ...&gt;
    &lt;dxg:TreeListControl.Resources&gt;
        &lt;local:CustomChildrenSelector x:Key=&quot;childrenSelector&quot;/&gt;
    &lt;/dxg:TreeListControl.Resources&gt;
    &lt;dxg:TreeListControl.View&gt;
        &lt;dxg:TreeListView TreeDerivationMode=&quot;ChildNodesSelector&quot;
                          ChildNodesSelector=&quot;{StaticResource childrenSelector}&quot;/&gt;
    &lt;/dxg:TreeListControl.View&gt;
&lt;/dxg:TreeListControl&gt;
</code></pre></section>

The asynchronous child nodes selector does not fetch nodes if the [TreeListView.EnableDynamicLoading](/WPF/DevExpress.Xpf.Grid.TreeListView.EnableDynamicLoading) property is set to `false`.

## Hierarchical Data Templates

[Run Demo: Hierarchical Data Templates](dxdemo://Wpf/DXTreeList/MainDemo/BuildTreeViaHierarchicalDataTemplate) [View Example: Use Hierarchical Data Templates to Build a Tree](https://github.com/DevExpress-Examples/wpf-treelist-use-hierarchical-data-templates-to-build-a-tree)

You can use templates to create a hierarchical data structure in the [TreeListView](/WPF/DevExpress.Xpf.Grid.TreeListView). An example of this structure is shown below:

- C#
- VB.NET

<section id="tabpanel_DIm0Hz1q2O-7_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code class="lang-csharp">public class ProjectObject : BaseObject {
    public ObservableCollection&lt;ProjectStage&gt; Stages { get; set; }
}

public class ProjectStage : BaseObject {
    public ObservableCollection&lt;Task&gt; Tasks { get; set; }
}

public class Task : BaseObject {
    State state;
    // ...
}
</code></pre></section>
<section id="tabpanel_DIm0Hz1q2O-7_tabid-vb" role="tabpanel" data-tab="tabid-vb" aria-hidden="true" hidden="hidden">
<pre><code class="lang-vb">Public Class ProjectObject
    Inherits BaseObject

    Public Property Stages As ObservableCollection(Of ProjectStage)
End Class

Public Class ProjectStage
    Inherits BaseObject

    Public Property Tasks As ObservableCollection(Of Task)
End Class

Public Class Task
    Inherits BaseObject

    Private state As State
    &#39; ...
End Class 
</code></pre></section>

If all objects have the same ***children*** field, create a hierarchical data template and assign it to the [TreeListView.DataRowTemplate](/WPF/DevExpress.Xpf.Grid.TreeListView.DataRowTemplate) property. You can put hierarchical data templates into resources. Specify the data type to which a template should be applied:

- XAML

<section id="tabpanel_DIm0Hz1q2O-8_tabid-xaml" role="tabpanel" data-tab="tabid-xaml">
<pre><code class="lang-xaml">&lt;ResourceDictionary&gt;
    &lt;HierarchicalDataTemplate DataType=&quot;{x:Type local:ProjectObject}&quot; ItemsSource=&quot;{Binding Path=Stages}&quot; /&gt;
    &lt;HierarchicalDataTemplate DataType=&quot;{x:Type local:ProjectStage}&quot; ItemsSource=&quot;{Binding Path=Tasks}&quot; /&gt;
&lt;/ResourceDictionary&gt;

&lt;dxg:TreeListControl.View&gt;
    &lt;dxg:TreeListView TreeDerivationMode=&quot;HierarchicalDataTemplate&quot; /&gt;
&lt;/dxg:TreeListControl.View&gt;
</code></pre></section>

If all objects have different ***children*** fields:

1. Create a template selector that implements the ***System.Windows.Controls.DataTemplateSelector*** and overrides the **SelectTemplate** method.

- XAML

<section id="tabpanel_DIm0Hz1q2O-9_tabid-xaml" role="tabpanel" data-tab="tabid-xaml">
<pre><code class="lang-xaml">&lt;Window.Resources&gt;
    &lt;ResourceDictionary&gt;
        &lt;local:CustomHierarchicalDataTemplateSelector x:Key=&quot;selector&quot;&gt;
            &lt;local:CustomHierarchicalDataTemplateSelector.ProjectDataTemplate&gt;
                &lt;HierarchicalDataTemplate ItemsSource=&quot;{Binding Path=Stages}&quot; /&gt;
            &lt;/local:CustomHierarchicalDataTemplateSelector.ProjectDataTemplate&gt;
            &lt;local:CustomHierarchicalDataTemplateSelector.ProjectStageDataTemplate&gt;
                &lt;HierarchicalDataTemplate ItemsSource=&quot;{Binding Path=Tasks}&quot; /&gt;
            &lt;/local:CustomHierarchicalDataTemplateSelector.ProjectStageDataTemplate&gt;
        &lt;/local:CustomHierarchicalDataTemplateSelector&gt;
    &lt;/ResourceDictionary&gt;
&lt;/Window.Resources&gt;
</code></pre></section>

- C#
    - VB.NET

<section id="tabpanel_DIm0Hz1q2O-10_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code class="lang-csharp">public class CustomHierarchicalDataTemplateSelector : DataTemplateSelector {

    public HierarchicalDataTemplate ProjectDataTemplate { get; set; }
    public HierarchicalDataTemplate ProjectStageDataTemplate { get; set; }

    public override System.Windows.DataTemplate SelectTemplate(object item, System.Windows.DependencyObject container) {
        var rowData = item as TreeListRowData;
        var element = rowData.Row;
        if (element is ProjectObject)
            return ProjectDataTemplate;
        if (element is ProjectStage)
            return ProjectStageDataTemplate;
        return null;
    }
}
</code></pre></section>
<section id="tabpanel_DIm0Hz1q2O-10_tabid-vb" role="tabpanel" data-tab="tabid-vb" aria-hidden="true" hidden="hidden">
<pre><code class="lang-vb">Public Class CustomHierarchicalDataTemplateSelector
    Inherits DataTemplateSelector

    Public Property ProjectDataTemplate As HierarchicalDataTemplate
    Public Property ProjectStageDataTemplate As HierarchicalDataTemplate

    Public Overrides Function SelectTemplate(ByVal item As Object, ByVal container As System.Windows.DependencyObject) As System.Windows.DataTemplate
        Dim rowData = TryCast(item, TreeListRowData)
        Dim element = rowData.Row
        If TypeOf element Is ProjectObject Then Return ProjectDataTemplate
        If TypeOf element Is ProjectStage Then Return ProjectStageDataTemplate
        Return Nothing
    End Function
End Class 
</code></pre></section>
2. Assign the template selector to the [TreeListView.DataRowTemplateSelector](/WPF/DevExpress.Xpf.Grid.TreeListView.DataRowTemplateSelector) property.
3. Set the [TreeListView.TreeDerivationMode](/WPF/DevExpress.Xpf.Grid.TreeListView.TreeDerivationMode) property to **HierarchicalDataTemplate**.

- XAML

<section id="tabpanel_DIm0Hz1q2O-11_tabid-xaml" role="tabpanel" data-tab="tabid-xaml">
<pre><code class="lang-xaml">&lt;dxg:TreeListControl.View&gt;
    &lt;dxg:TreeListView DataRowTemplateSelector=&quot;{StaticResource selector}&quot;
                      TreeDerivationMode=&quot;HierarchicalDataTemplate&quot; /&gt;
&lt;/dxg:TreeListControl.View&gt;
</code></pre></section>

Note

- First, the [TreeListView](/WPF/DevExpress.Xpf.Grid.TreeListView) verifies its [TreeListView.DataRowTemplateSelector](/WPF/DevExpress.Xpf.Grid.TreeListView.DataRowTemplateSelector) property. If the specified node selector returns **null**, or the [TreeListView.DataRowTemplateSelector](/WPF/DevExpress.Xpf.Grid.TreeListView.DataRowTemplateSelector) property is not specified, it uses a template the [TreeListView.DataRowTemplate](/WPF/DevExpress.Xpf.Grid.TreeListView.DataRowTemplate) property specifies. If this property is not specified, an implicit hierarchical data template is used.
- If the **HierarchicalDataTemplate** is defined for a node, its **ItemTemplate** and **ItemTemplateSelector** properties take precedence over the [TreeListView.DataRowTemplate](/WPF/DevExpress.Xpf.Grid.TreeListView.DataRowTemplate) and [TreeListView.DataRowTemplateSelector](/WPF/DevExpress.Xpf.Grid.TreeListView.DataRowTemplateSelector) properties.

## Related API

### Sort and Filter in Hierarchical Binding Mode

When the [TreeListView](/WPF/DevExpress.Xpf.Grid.TreeListView) is in hierarchical binding mode, users can sort and filter values if object types are the same. Set the [TreeListView.AutoDetectColumnTypeInHierarchicalMode](/WPF/DevExpress.Xpf.Grid.TreeListView.AutoDetectColumnTypeInHierarchicalMode) property to **true** to allow sorting/filtering (enabled by default).

### Control whether to Create Child Nodes

You can control whether to create child nodes for a node. The following example shows how to prevent the [TreeListView](/WPF/DevExpress.Xpf.Grid.TreeListView) from creating child nodes for the **Information Gathering** node:

![](/WPF/images/has-children-node-path.png)

[View Example: Control whether to Create Child Nodes](https://github.com/DevExpress-Examples/wpf-tree-list-control-whether-to-create-child-nodes)

1. In a data source, create a field that determines whether a node has children (the **HasChildNodes** field in the code sample below):

- C#
    - VB.NET

<section id="tabpanel_DIm0Hz1q2O-12_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code class="lang-csharp">public class BaseObject {
    public string Name { get; set; }
    public string Executor { get; set; }
    public ObservableCollection&lt;Task&gt; Tasks { get; set; }
    public bool HasChildNodes { get; set; }
}

public class ProjectObject : BaseObject { }

public class Task : BaseObject {
    public string State { get; set; }
}

public class ViewModel {
    ObservableCollection&lt;ProjectObject&gt; InitData() {
        ObservableCollection&lt;ProjectObject&gt; projects = new ObservableCollection&lt;ProjectObject&gt;();

        ProjectObject betaronProject = new ProjectObject() { Name = &quot;Project: Betaron&quot;, Executor = &quot;Mcfadyen Ball&quot;, Tasks = new ObservableCollection&lt;Task&gt;(), HasChildNodes = true };

        Task Task11 = new Task() { Name = &quot;Information Gathering&quot;, Executor = &quot;Kaiden Savastano&quot;, Tasks = new ObservableCollection&lt;Task&gt;(), HasChildNodes = false };
        Task11.Tasks.Add(new Task() { Name = &quot;Market research&quot;, Executor = &quot;Carmine Then&quot;, State = &quot;Completed&quot;, HasChildNodes = false });
        Task11.Tasks.Add(new Task() { Name = &quot;Making specification&quot;, Executor = &quot;Seto Kober&quot;, State = &quot;In progress&quot;, HasChildNodes = false });

        Task Task12 = new Task() { Name = &quot;Planning&quot;, Executor = &quot;Manley Difrancesco&quot;, Tasks = new ObservableCollection&lt;Task&gt;(), HasChildNodes = true };
        Task12.Tasks.Add(new Task() { Name = &quot;Documentation&quot;, Executor = &quot;Martez Gollin&quot;, State = &quot;Not started&quot;, HasChildNodes = true });

        // ...    

        ProjectObject stantoneProject = new ProjectObject() { Name = &quot;Project: Stanton&quot;, Executor = &quot;Ruben Ackerman&quot;, Tasks = new ObservableCollection&lt;Task&gt;(), HasChildNodes = true };

        Task Task21 = new Task() { Name = &quot;Information Gathering&quot;, Executor = &quot;Huyen Trinklein&quot;, Tasks = new ObservableCollection&lt;Task&gt;(), HasChildNodes = false };
        Task21.Tasks.Add(new Task() { Name = &quot;Market research&quot;, Executor = &quot;Tanner Crittendon&quot;, State = &quot;Completed&quot;, HasChildNodes = false });
        Task21.Tasks.Add(new Task() { Name = &quot;Making specification&quot;, Executor = &quot;Carmine Then&quot;, State = &quot;Completed&quot;, HasChildNodes = false });

        Task Task22 = new Task() { Name = &quot;Planning&quot;, Executor = &quot;Alfredo Sookoo&quot;, Tasks = new ObservableCollection&lt;Task&gt;(), HasChildNodes = true };
        Task22.Tasks.Add(new Task() { Name = &quot;Documentation&quot;, Executor = &quot;Gorf Wobbe&quot;, State = &quot;Completed&quot;, HasChildNodes = true });

        // ...
    }
} 
</code></pre></section>
<section id="tabpanel_DIm0Hz1q2O-12_tabid-vb" role="tabpanel" data-tab="tabid-vb" aria-hidden="true" hidden="hidden">
<pre><code class="lang-vb">Public Class BaseObject
    Public Property Name As String
    Public Property Executor As String
    Public Property Tasks As ObservableCollection(Of Task)
    Public Property HasChildNodes As Boolean
End Class

Public Class ProjectObject
    Inherits BaseObject
End Class

Public Class Task
    Inherits BaseObject

    Public Property State As String
End Class

Public Class ViewModel
    Private Function InitData() As ObservableCollection(Of ProjectObject)
        Dim projects As ObservableCollection(Of ProjectObject) = New ObservableCollection(Of ProjectObject)()

        Dim betaronProject As ProjectObject = New ProjectObject() With { .Name = &quot;Project: Betaron&quot;, .Executor = &quot;Mcfadyen Ball&quot;, .Tasks = New ObservableCollection(Of Task)(), .HasChildNodes = True }
        Dim Task11 As Task = New Task() With { .Name = &quot;Information Gathering&quot;, .Executor = &quot;Kaiden Savastano&quot;, .Tasks = New ObservableCollection(Of Task)(), .HasChildNodes = False }
        Task11.Tasks.Add(New Task() With { .Name = &quot;Market research&quot;, .Executor = &quot;Carmine Then&quot;, .State = &quot;Completed&quot;, .HasChildNodes = False })
        Task11.Tasks.Add(New Task() With { .Name = &quot;Making specification&quot;, .Executor = &quot;Seto Kober&quot;, .State = &quot;In progress&quot;, .HasChildNodes = False })
        Dim Task12 As Task = New Task() With { .Name = &quot;Planning&quot;, .Executor = &quot;Manley Difrancesco&quot;, .Tasks = New ObservableCollection(Of Task)(), .HasChildNodes = True }
        Task12.Tasks.Add(New Task() With { .Name = &quot;Documentation&quot;, .Executor = &quot;Martez Gollin&quot;, .State = &quot;Not started&quot;, .HasChildNodes = True })

        &#39; ...

        Dim stantoneProject As ProjectObject = New ProjectObject() With { .Name = &quot;Project: Stanton&quot;, .Executor = &quot;Ruben Ackerman&quot;, .Tasks = New ObservableCollection(Of Task)(), .HasChildNodes = True }

        Dim Task21 As Task = New Task() With {.Name = &quot;Information Gathering&quot;, .Executor = &quot;Huyen Trinklein&quot;, .Tasks = New  .HasChildNodes = False }
        Task21.Tasks.Add(New Task() With { .Name = &quot;Market research&quot;, .Executor = &quot;Tanner Crittendon&quot;, .State = &quot;Completed&quot;, .HasChildNodes = False })
        Task21.Tasks.Add(New Task() With { .Name = &quot;Making specification&quot;, .Executor = &quot;Carmine Then&quot;, .State = &quot;Completed&quot;, .HasChildNodes = False })

        Dim Task22 As Task = New Task() With { .Name = &quot;Planning&quot;, .Executor = &quot;Alfredo Sookoo&quot;, .Tasks = New ObservableCollection(Of Task)(), .HasChildNodes = True }
        Task22.Tasks.Add(New Task() With { .Name = &quot;Documentation&quot;, .Executor = &quot;Gorf Wobbe&quot;, .State = &quot;Completed&quot;, .HasChildNodes = True
        })

        &#39; ...
    End Function
End Class 
</code></pre></section>
2. Set the [TreeListView.HasChildNodesPath](/WPF/DevExpress.Xpf.Grid.TreeListView.HasChildNodesPath) property to this field’s name.

- Xaml

<section id="tabpanel_DIm0Hz1q2O-13_tabid-xaml" role="tabpanel" data-tab="tabid-xaml">
<pre><code class="lang-xaml">&lt;dxg:GridControl Name=&quot;treeListView1&quot; ItemsSource=&quot;{Binding DataItems}&quot;&gt;
    &lt;dxg:GridControl.Columns&gt;
        &lt;dxg:GridColumn FieldName=&quot;Name&quot;/&gt;
        &lt;dxg:GridColumn FieldName=&quot;Executor&quot;/&gt;
        &lt;dxg:GridColumn FieldName=&quot;State&quot;/&gt;
    &lt;/dxg:GridControl.Columns&gt;
    &lt;dxg:GridControl.View&gt;
        &lt;dxg:TreeListView TreeDerivationMode=&quot;ChildNodesSelector&quot; ChildNodesPath=&quot;Tasks&quot; HasChildNodesPath=&quot;HasChildNodes&quot;/&gt;
    &lt;/dxg:GridControl.View&gt;
&lt;/dxg:GridControl&gt;
</code></pre></section>