All docs
V20.2
20.2
20.1
The page you are viewing does not exist in version 20.1. This link will take you to the root page.
19.2
The page you are viewing does not exist in version 19.2. This link will take you to the root page.
19.1
The page you are viewing does not exist in version 19.1. This link will take you to the root page.
18.2
The page you are viewing does not exist in version 18.2. This link will take you to the root page.
18.1
The page you are viewing does not exist in version 18.1. This link will take you to the root page.
17.2
The page you are viewing does not exist in version 17.2. This link will take you to the root page.

TreeViewControl.TreeDerivationMode Property

Gets or sets the tree derivation mode. This is a dependency property.

Namespace: DevExpress.Xpf.Grid

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

Declaration

public TreeDerivationMode TreeDerivationMode { get; set; }
Public Property TreeDerivationMode As TreeDerivationMode

Property Value

Type Default Description
TreeDerivationMode

ChildNodesSelector

The tree derivation mode.

Available values:

Name Description
Selfreference

Builds a tree from a self-referential data structure. To learn more, see Binding to Self-Referential Data Structure.

ChildNodesSelector

You should manually write code to specify where a data object's child items come from by creating a selector class. To learn more, see Binding to Hierarchical Data Structure.

HierarchicalDataTemplate

Builds a tree using Hierarchical Data Templates. To learn more, see Binding to Hierarchical Data Structure.

Remarks

The TreeViewControl can display information in a tree from a self-referential (flat) or hierarchical data structure. The TreeDerivationMode property specifies the corresponding tree derivation modes for each data structure:

Data Structure Type

Tree Derivation Mode

Self-Referential (Flat)

Self-Reference

Hierarchical

Child Nodes Selector

Child Nodes Path

Hierarchical Data Template

ChildNodesSelector

The Child Nodes Selector returns node children. You can use this approach to create a hierarchical data structure for different object types.

Use the Child Nodes Selector to create a hierarchical data structure in the TreeViewControl. An example of this structure is shown below:

public class ProjectObject : BaseObject {
    public ObservableCollection<ProjectStage> Stages { get; set; }
}

public class ProjectStage : BaseObject {
    public ObservableCollection<Task> Tasks { get; set; }
}

public class Task : BaseObject {
    State state;
    // ...
}
  1. Create a selector class that implements DevExpress.Xpf.Grid.IChildNodeSelector, and override the SelectChildren method that returns node children.

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

    public class CustomChildrenSelector : IChildNodesSelector {
        public IEnumerable SelectChildren(object item) {
            if (item is Task)
                return null;
            else if (item is ProjectStage)
                return (item as ProjectStage).Tasks;
            else if (item is ProjectObject)
                return (item as ProjectObject).Stages;
            return null;
        }
    }
    
  2. Assign the Child Nodes Selector to the ChildNodesSelector property.

    <dxg:TreeViewControl ItemsSource="{Binding DataItems}" 
                         TreeViewFieldName="Name">
        <dxg:TreeViewControl.ChildNodesSelector>
            <local:CustomChildrenSelector/>
        </dxg:TreeViewControl.ChildNodesSelector>
    </dxg:TreeViewControl>
    

ChildNodesPath

Use the Child Nodes Path to bind the TreeViewControl to a collection if all objects have the same field that contains child nodes.

In this mode, you can use the HasChildNodesPath property to control whether a node has children.

To build a tree structure, set the ChildNodesPath property to a field that contains child nodes (the Employees field in the code sample below).

<dxg:TreeViewControl ItemsSource="{Binding EmployeeDepartments}" 
                     ChildNodesPath="Employees" 
                     TreeViewFieldName="Name"
                     HasChildNodesPath="HasChildNodes"/>
using System.Windows;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using DevExpress.Mvvm;

namespace TreeViewChildNodesSelector {
    public class MainWindowViewModel : ViewModelBase {
        public MainWindowViewModel() {
            EmployeeDepartments = Departments.GetDepartments();
        }
        public List<EmployeeDepartment> EmployeeDepartments { get; set; }
    }
    public class Employee {
        public Employee(int id, string name) {
            ID = id;
            Name = name;
        }
        public int ID { get; set; }
        public string Name { get; set; }
    }
    public class EmployeeDepartment {
        public string Name { get; set; }
        public ObservableCollection<Employee> Employees { get; }
        public bool HasChildNodes { get; set; }

        public EmployeeDepartment(string name, IEnumerable<Employee> employees) {
            Name = name;
            Employees = new ObservableCollection<Employee>(employees);
        }
    }
    public static class Departments {
        public static List<EmployeeDepartment> GetDepartments() {
            List<EmployeeDepartment> departments = new List<EmployeeDepartment> {
                new EmployeeDepartment("Management", new Employee[] {
                new Employee(0, "Gregory S. Price")
                }, true),
                new EmployeeDepartment("Marketing", new Employee[] {
                new Employee(1, "Irma R. Marshall"),
                new Employee(2, "Brian C. Cowling"),
                new Employee(3, "Thomas C. Dawson"),
                new Employee(4, "Bryan R. Henderson"),
                }, true),
                new EmployeeDepartment("Operations", new Employee[] {
                new Employee(5, "John C. Powell"),
                new Employee(6, "Harold S. Brandes"),
                new Employee(7, "Jan K. Sisk"),
                new Employee(8, "Sidney L. Holder"),
                }, true),
                new EmployeeDepartment("Production", new Employee[] {
                new Employee(9, "Christian P. Laclair"),
                new Employee(10, "James L. Kelsey"),
                new Employee(11, "Howard M. Carpenter"),
                new Employee(12, "Jennifer T. Tapia"),
                },false),
                new EmployeeDepartment("Finance", new Employee[] {
                new Employee(13, "Karen J. Kelly"),
                new Employee(14, "Judith P. Underhill"),
                new Employee(15, "Russell E. Belton"),
                },false)
            };
            return departments;
        }
    }
}

Selfreference

Set the TreeDerivationMode property to Selfreference to enable the self-referential mode.

To build a tree structure, your data source should contain the following two fields with the same data type:

  • Key Field - This field should contain unique values used to identify nodes. Assign its name to the KeyFieldName property.
  • Parent Field - This field should contain values that indicate parent nodes. Assign its name to the ParentFieldName property.

In this mode, you can specify the RootValue property to add to the collection of root nodes only nodes with the specified parent field value.

<dxg:TreeViewControl ItemsSource="{Binding Employees}" 
                     TreeDerivationMode="Selfreference"
                     KeyFieldName="ID" 
                     ParentFieldName="ParentID" 
                     TreeViewFieldName="Name">
    <dxg:TreeViewControl.RootValue>
        <sys:Int32>1</sys:Int32>
    </dxg:TreeViewControl.RootValue>
</dxg:TreeViewControl>
using System.Windows;
using System.Collections.Generic;
using DevExpress.Mvvm;

namespace TreeViewSelfreference {
    public class Employee : BindableBase {
        public int ID { get; set; }
        public int ParentID { get; set; }
        public string Name { get; set; }
        public string Position { get; set; }
        public string Department { get; set; }
    }
    public static class Staff {
        public static List<Employee> GetStaff() {
            List<Employee> staff = new List<Employee> {
                new Employee() { ID = 1, ParentID = 0, Name = "Gregory S. Price", Department = "", Position = "President" },
                new Employee() { ID = 2, ParentID = 1, Name = "Irma R. Marshall", Department = "Marketing", Position = "Vice President" },
                new Employee() { ID = 3, ParentID = 1, Name = "John C. Powell", Department = "Operations", Position = "Vice President" },
                new Employee() { ID = 4, ParentID = 1, Name = "Christian P. Laclair", Department = "Production", Position = "Vice President" },
                new Employee() { ID = 5, ParentID = 1, Name = "Karen J. Kelly", Department = "Finance", Position = "Vice President" },
                new Employee() { ID = 6, ParentID = 2, Name = "Brian C. Cowling", Department = "Marketing", Position = "Manager" },
                new Employee() { ID = 7, ParentID = 2, Name = "Thomas C. Dawson", Department = "Marketing", Position = "Manager" },
                new Employee() { ID = 8, ParentID = 2, Name = "Angel M. Wilson", Department = "Marketing", Position = "Manager" },
                new Employee() { ID = 9, ParentID = 2, Name = "Bryan R. Henderson", Department = "Marketing", Position = "Manager" },
                new Employee() { ID = 10, ParentID = 3, Name = "Harold S. Brandes", Department = "Operations", Position = "Manager" },
                new Employee() { ID = 11, ParentID = 3, Name = "Michael S. Blevins", Department = "Operations", Position = "Manager" },
                new Employee() { ID = 12, ParentID = 3, Name = "Jan K. Sisk", Department = "Operations", Position = "Manager" },
                new Employee() { ID = 13, ParentID = 3, Name = "Sidney L. Holder", Department = "Operations", Position = "Manager" },
                new Employee() { ID = 14, ParentID = 4, Name = "James L. Kelsey", Department = "Production", Position = "Manager" },
                new Employee() { ID = 15, ParentID = 4, Name = "Howard M. Carpenter", Department = "Production", Position = "Manager" },
                new Employee() { ID = 16, ParentID = 4, Name = "Jennifer T. Tapia", Department = "Production", Position = "Manager" },
                new Employee() { ID = 17, ParentID = 5, Name = "Judith P. Underhill", Department = "Finance", Position = "Manager" },
                new Employee() { ID = 18, ParentID = 5, Name = "Russell E. Belton", Department = "Finance", Position = "Manager" }
            };
            return staff;
        }
    }
    public class MainWindowViewModel : ViewModelBase {
        public MainWindowViewModel() {
            Employees = Staff.GetStaff();
        }
        public List<Employee> Employees { get; private set; }
    }
}

HierarchicalDataTemplate

You can use templates to create a hierarchical data structure in the TreeViewControl. An example of this structure is shown below:

public class ProjectObject : BaseObject {
    public ObservableCollection<ProjectStage> Stages { get; set; }
}

public class ProjectStage : BaseObject {
    public ObservableCollection<Task> Tasks { get; set; }
}

public class Task : BaseObject {
    State state;
    // ...
}

If all objects have the same field that contains child nodes, create a hierarchical data template and assign it to the NodeTemplate property. You can put hierarchical data templates into resources. Specify the data type to which a template should be applied:

<Window.Resources>
    <HierarchicalDataTemplate DataType="{x:Type local:ProjectObject}" ItemsSource="{Binding Path=Stages}" />
    <HierarchicalDataTemplate DataType="{x:Type local:ProjectStage}" ItemsSource="{Binding Path=Tasks}" />
</Window.Resources>

<dxg:TreeViewControl ItemsSource="{Binding DataItems}" 
                     TreeViewFieldName="Name" 
                     TreeDerivationMode="HierarchicalDataTemplate"/>

If all objects have different fields that contain child nodes:

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

    <Window.Resources>
        <ResourceDictionary>
            <local:CustomHierarchicalDataTemplateSelector x:Key="selector">
                <local:CustomHierarchicalDataTemplateSelector.ProjectDataTemplate>
                    <HierarchicalDataTemplate ItemsSource="{Binding Path=Stages}" />
                </local:CustomHierarchicalDataTemplateSelector.ProjectDataTemplate>
                <local:CustomHierarchicalDataTemplateSelector.ProjectStageDataTemplate>
                    <HierarchicalDataTemplate ItemsSource="{Binding Path=Tasks}" />
                </local:CustomHierarchicalDataTemplateSelector.ProjectStageDataTemplate>
            </local:CustomHierarchicalDataTemplateSelector>
        </ResourceDictionary>
    </Window.Resources>
    
    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 DevExpress.Xpf.Grid.TreeList.TreeListRowData;
            var element = rowData.Row;
            if (element is ProjectObject)
                return ProjectDataTemplate;
            if (element is ProjectStage)
                return ProjectStageDataTemplate;
            return null;
        }
    }
    
  2. Assign the template selector to the NodeTemplateSelector property.

  3. Set the TreeDerivationMode property to HierarchicalDataTemplate.

    <dxg:TreeViewControl TreeDerivationMode="HierarchicalDataTemplate"
                         NodeTemplateSelector="{StaticResource selector}"/>
    
See Also