Skip to main content

Display Hierarchical Data in Tree View for .NET MAUI

  • 3 minutes to read

The DXTreeView control allows you to display information in a tree from a self-referential (flat) or hierarchical data structure. Use the TreeDescription property to specify and configure the data structure.

Self-Referential Data Structure

The Tree View can display information from self-referential data structures. To build the tree structure, the data source should contain two fields with the same data type:

KeyFieldName
The name of the service field in a data source that contains unique values used to identify nodes.
ParentFieldName
The name of the service field in a data source that identifies parent nodes.

Note

The KeyFieldName value of a parent node is equal to the ParentFieldName value of a child node in a tree structure.

The following code snippet builds a tree from a self-referential data structure:

DevExpress Tree View for MAUI - Self-Referential Data Structure

<dxt:DXTreeView ...
    x:Name="treeView"
    ItemsSource="{Binding Nodes}" 
    ItemTemplate="{StaticResource nodeTemplate}"
    DisplayMember="Name">
    <dxt:DXTreeView.TreeDescription>
        <dxt:SelfReferenceTreeDescription KeyFieldName="Id" ParentFieldName="ParentId"/>
    </dxt:DXTreeView.TreeDescription>
</dxt:DXTreeView>
[
    {
    "Id": 140,
    "ParentId": 109,
    "FirstName": "Abigail",
    "LastName": "Bunch",
    "JobTitle": "Chief Financial Officer",
    ...
  },
  {
    "Id": 139,
    "ParentId": 140,
    "FirstName": "George",
    "LastName": "Holloway",
    "JobTitle": "Accounts Manager",
    ...
  },
]

Root Value

If you want to specify a custom root node value, use the RootValue property:

<dxt:DXTreeView ...
    x:Name="treeView"
    ItemsSource="{Binding Nodes}" 
    ItemTemplate="{StaticResource nodeTemplate}"
    DisplayMember="Name">
    <dxt:DXTreeView.TreeDescription>
        <dxt:SelfReferenceTreeDescription KeyFieldName="Id" ParentFieldName="ParentId">
            <dxt:SelfReferenceTreeDescription.RootValue>
                <x:Int32>109</x:Int32>
            </dxt:SelfReferenceTreeDescription.RootValue>
        </dxt:SelfReferenceTreeDescription>
    </dxt:DXTreeView.TreeDescription>
</dxt:DXTreeView>

Hierarchical Data Structure

The Tree View can display information from a hierarchical data structure. The hierarchical data structure is a set of nested objects where a parent field contains child records. Parents and children can be of different object types.

The ItemsSource property contains only data items that correspond to root nodes. You can use the following properties to make the Tree View work with the hierarchical data structure:

ChildNodeFieldName
Sets a path to the child field. Use this property only when child and parent fields have the same object type.
ChildNodeSelector
Creates a selector that returns node children. You can use this property for different object types.

The following code snippet uses the ChildNodeFieldName approach to specify a hierarchical data structure:

DevExpress Tree View for MAUI - Hierarchical Data Structure

<dxt:DXTreeView ...
    x:Name="treeView"
    ItemsSource="{Binding Nodes}" 
    ItemTemplate="{StaticResource nodeTemplate}"
    DisplayMember="Name" >
    <dxt:DXTreeView.TreeDescription>
        <dxt:HierarchyTreeDescription ChildNodeFieldName="Nodes"/>
    </dxt:DXTreeView.TreeDescription>
</dxt:DXTreeView>
public class ReportLibraryViewModel {
    public ObservableCollection<ReportLibraryNode> Nodes { get; }
    public ReportLibraryViewModel() {
        Nodes = new();

        var customers = new ReportLibraryNode() { Name = "Customers", IsFolder = true };
        var orders = new ReportLibraryNode() { Name = "Orders", IsFolder = true };
        orders.Nodes.Add(new ReportLibraryNode() { Name = "Detail.pdf" });
        orders.Nodes.Add(new ReportLibraryNode() { Name = "Summary.pdf" });
        customers.Nodes.Add(orders);
        customers.Nodes.Add(new ReportLibraryNode() { Name = "Balance sheet.pdf" });
        customers.Nodes.Add(new ReportLibraryNode() { Name = "Revenue by company.pdf" });
        Nodes.Add(customers);

        var employees = new ReportLibraryNode() { Name = "Employees", IsFolder = true };
        employees.Nodes.Add(new ReportLibraryNode() { Name = "Arrival card.pdf" });
        employees.Nodes.Add(new ReportLibraryNode() { Name = "Employee comparison.pdf" });
        employees.Nodes.Add(new ReportLibraryNode() { Name = "Employee location.pdf" });
        employees.Nodes.Add(new ReportLibraryNode() { Name = "Employee performance review.pdf" });
        employees.Nodes.Add(new ReportLibraryNode() { Name = "Letter.pdf" });
        Nodes.Add(employees);

        //...
    }
}

public class ReportLibraryNode {
    public string Name { get; init; }
    public bool IsFolder { get; init; }
    public ObservableCollection<ReportLibraryNode> Nodes { get; } = new();
}