Skip to main content

TreeListView.HasChildNodesPath Property

Gets or sets a name of a data source’s field that determines whether a node has children. This is a dependency property.

Namespace: DevExpress.Xpf.Grid

Assembly: DevExpress.Xpf.Grid.v24.2.dll

NuGet Package: DevExpress.Wpf.Grid.Core

Declaration

public string HasChildNodesPath { get; set; }

Property Value

Type Description
String

The name of a data source’s field that determines whether a node has children.

Remarks

Note

A TreeListView with the Self-Referential data structure (TreeDerivationMode is set to Selfreference) ignores the HasChildNodesPath property.

Control Expand Buttons when Sub-level Children are not Fetched

The TreeListView in hierarchical binding mode fetches child nodes of sub-level nodes when you expand their parent node. If the TreeListView.FetchSublevelChildrenOnExpand property is false, all the child nodes display expand buttons (even if they do not have children) after you expand their parent node. The expand button is hidden when you expand a sub-level node that does not contain child nodes:

<dxg:GridControl Name="treeListView1" ItemsSource="{Binding DataItems}">
    <dxg:GridControl.Columns>
        <dxg:GridColumn FieldName="Name"/>
        <dxg:GridColumn FieldName="Executor"/>
        <dxg:GridColumn FieldName="State"/>
    </dxg:GridControl.Columns>
    <dxg:GridControl.View>
        <dxg:TreeListView TreeDerivationMode="ChildNodesSelector" ChildNodesPath="Tasks" 
                          FetchSublevelChildrenOnExpand="False"/>
    </dxg:GridControl.View>
</dxg:GridControl>

You can make a node display an expand button only if this node has children:

  1. In a data source, create a field that determines whether a node has children (the HasChildNodes field in the code sample below). In this case, the TreeListView will know for which nodes display expand buttons:

    public class BaseObject {
        public string Name { get; set; }
        public string Executor { get; set; }
        public ObservableCollection<Task> 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<ProjectObject> InitData() {
            ObservableCollection<ProjectObject> projects = new ObservableCollection<ProjectObject>();
    
            ProjectObject betaronProject = new ProjectObject() { Name = "Project: Betaron", Executor = "Mcfadyen Ball", Tasks = new ObservableCollection<Task>(), HasChildNodes = true };
    
            Task Task11 = new Task() { Name = "Information Gathering", Executor = "Kaiden Savastano", Tasks = new ObservableCollection<Task>(), HasChildNodes = true };
            Task11.Tasks.Add(new Task() { Name = "Market research", Executor = "Carmine Then", State = "Completed", HasChildNodes = false });
            Task11.Tasks.Add(new Task() { Name = "Making specification", Executor = "Seto Kober", State = "In progress", HasChildNodes = false });
    
            Task Task12 = new Task() { Name = "Planning", Executor = "Manley Difrancesco", Tasks = new ObservableCollection<Task>(), HasChildNodes = true };
            Task12.Tasks.Add(new Task() { Name = "Documentation", Executor = "Martez Gollin", State = "Not started", HasChildNodes = false });
    
            // ...    
    
            ProjectObject stantoneProject = new ProjectObject() { Name = "Project: Stanton", Executor = "Ruben Ackerman", Tasks = new ObservableCollection<Task>(), HasChildNodes = true };
    
            Task Task21 = new Task() { Name = "Information Gathering", Executor = "Huyen Trinklein", Tasks = new ObservableCollection<Task>(), HasChildNodes = true };
            Task21.Tasks.Add(new Task() { Name = "Market research", Executor = "Tanner Crittendon", State = "Completed", HasChildNodes = false });
            Task21.Tasks.Add(new Task() { Name = "Making specification", Executor = "Carmine Then", State = "Completed", HasChildNodes = false });
    
            Task Task22 = new Task() { Name = "Planning", Executor = "Alfredo Sookoo", Tasks = new ObservableCollection<Task>(), HasChildNodes = true };
            Task22.Tasks.Add(new Task() { Name = "Documentation", Executor = "Gorf Wobbe", State = "Completed", HasChildNodes = false });
    
            // ...
        }
    } 
    
  2. Specify the TreeListView.HasChildNodesPath property to this field’s name:

    <dxg:GridControl Name="treeListView1" ItemsSource="{Binding DataItems}">
        <dxg:GridControl.Columns>
            <dxg:GridColumn FieldName="Name"/>
            <dxg:GridColumn FieldName="Executor"/>
            <dxg:GridColumn FieldName="State"/>
        </dxg:GridControl.Columns>
        <dxg:GridControl.View>
            <dxg:TreeListView TreeDerivationMode="ChildNodesSelector" ChildNodesPath="Tasks" 
                              FetchSublevelChildrenOnExpand="False"
                              HasChildNodesPath="HasChildNodes"/>
        </dxg:GridControl.View>
    </dxg:GridControl>
    

View Example: Control Visibility of Expand Buttons when Sub-level Children are not Fetched

Read Tutorial: Expand and Collapse Nodes

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 from creating child nodes for the Information Gathering node:

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

    public class BaseObject {
        public string Name { get; set; }
        public string Executor { get; set; }
        public ObservableCollection<Task> 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<ProjectObject> InitData() {
            ObservableCollection<ProjectObject> projects = new ObservableCollection<ProjectObject>();
    
            ProjectObject betaronProject = new ProjectObject() { Name = "Project: Betaron", Executor = "Mcfadyen Ball", Tasks = new ObservableCollection<Task>(), HasChildNodes = true };
    
            Task Task11 = new Task() { Name = "Information Gathering", Executor = "Kaiden Savastano", Tasks = new ObservableCollection<Task>(), HasChildNodes = false };
            Task11.Tasks.Add(new Task() { Name = "Market research", Executor = "Carmine Then", State = "Completed", HasChildNodes = false });
            Task11.Tasks.Add(new Task() { Name = "Making specification", Executor = "Seto Kober", State = "In progress", HasChildNodes = false });
    
            Task Task12 = new Task() { Name = "Planning", Executor = "Manley Difrancesco", Tasks = new ObservableCollection<Task>(), HasChildNodes = true };
            Task12.Tasks.Add(new Task() { Name = "Documentation", Executor = "Martez Gollin", State = "Not started", HasChildNodes = true });
    
            // ...    
    
            ProjectObject stantoneProject = new ProjectObject() { Name = "Project: Stanton", Executor = "Ruben Ackerman", Tasks = new ObservableCollection<Task>(), HasChildNodes = true };
    
            Task Task21 = new Task() { Name = "Information Gathering", Executor = "Huyen Trinklein", Tasks = new ObservableCollection<Task>(), HasChildNodes = false };
            Task21.Tasks.Add(new Task() { Name = "Market research", Executor = "Tanner Crittendon", State = "Completed", HasChildNodes = false });
            Task21.Tasks.Add(new Task() { Name = "Making specification", Executor = "Carmine Then", State = "Completed", HasChildNodes = false });
    
            Task Task22 = new Task() { Name = "Planning", Executor = "Alfredo Sookoo", Tasks = new ObservableCollection<Task>(), HasChildNodes = true };
            Task22.Tasks.Add(new Task() { Name = "Documentation", Executor = "Gorf Wobbe", State = "Completed", HasChildNodes = true });
    
            // ...
        }
    } 
    
  2. Specify the TreeListView.HasChildNodesPath property to this field’s name:

    <dxg:GridControl Name="treeListView1" ItemsSource="{Binding DataItems}">
        <dxg:GridControl.Columns>
            <dxg:GridColumn FieldName="Name"/>
            <dxg:GridColumn FieldName="Executor"/>
            <dxg:GridColumn FieldName="State"/>
        </dxg:GridControl.Columns>
        <dxg:GridControl.View>
            <dxg:TreeListView TreeDerivationMode="ChildNodesSelector" ChildNodesPath="Tasks" HasChildNodesPath="HasChildNodes"/>
        </dxg:GridControl.View>
    </dxg:GridControl>
    

View Example: Control Whether to Create Child Nodes

Read Tutorial: Bind to Hierarchical Data Structure

See Also