Skip to main content

Custom Nodes

  • 5 minutes to read

Custom nodes, which are TreeListNode descendants, allow you to extend the default node capabilities. This topic shows how to create custom nodes and use them in a Tree List control.

Custom Nodes

Nodes of the Tree List control (TreeListNode objects) are not created directly. The Tree List control doesn’t call the TreeListNode constructor. Instead, it calls the protected CreateNode method each time a new node needs to be created. This method has the following syntax:

protected virtual TreeListNode CreateNode(int nodeID, TreeListNodes owner);

This method must return the newly created node. The nodeID and owner parameters specify the node’s identifier and the owning collection. The first parameter corresponds to the TreeListNode.Id property. The second parameter is the parent node’s TreeListNode.Nodes property value. (If a root level node is created, the owner parameter is equal to the TreeList.Nodes property value.)

The following technique allows you to create custom nodes:

  • Create a TreeListNode descendant with the required functionality.
  • Create a TreeList control descendant, and override the CreateNode method, to return a newly created node of a custom type.
  • Add the derived control to the form.


This example shows how to create a custom node class that introduces a Height property. This property will allow heights to be set for individual nodes.


View Example

using DevExpress.XtraTreeList;
using DevExpress.XtraTreeList.Nodes;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace CustomTreeList_NodeHeight {
    public partial class Form1 : Form {
        public Form1() {

            List<MyRecord> list = new List<MyRecord>();
            list.Add(new MyRecord(0, -1, "Corporate Headquarters", 1000000, "Monterey"));
            list.Add(new MyRecord(1, 0, "Sales and Marketing", 22000, "San Francisco"));
            list.Add(new MyRecord(2, 0, "Finance", 40000, "Monterey"));
            list.Add(new MyRecord(3, 0, "Engineering", 1100000, "Monterey"));
            list.Add(new MyRecord(4, -1, "Customer Services", 850000, "Burlington, VT"));

            treeList1.DataSource = list;
            treeList1.Columns["Budget"].Format.FormatType = DevExpress.Utils.FormatType.Numeric;
            treeList1.Columns["Budget"].Format.FormatString = "c0";


        private void Form1_Load(object sender, EventArgs e) {
            ((MyTreeListNode)treeList1.Nodes[0]).Height = 35;
            ((MyTreeListNode)treeList1.Nodes[0].Nodes[1]).Height = 35;


    public class MyTreeList : TreeList {
        public MyTreeList() : base() {
            OptionsBehavior.AutoNodeHeight = false;

        protected override TreeListNode CreateNode(int nodeID, TreeListNodes owner, object tag) {
            return new MyTreeListNode(nodeID, owner);
        protected override void InternalNodeChanged(TreeListNode node, TreeListNodes nodes, NodeChangeTypeEnum changeType) {
            if (changeType == NodeChangeTypeEnum.User1)
            base.InternalNodeChanged(node, nodes, changeType);
        protected override void RaiseCalcNodeHeight(TreeListNode node, ref int nodeHeight) {
            MyTreeListNode myNode = node as MyTreeListNode;
            if (myNode != null)
                nodeHeight = myNode.Height;
                base.RaiseCalcNodeHeight(node, ref nodeHeight);
        public virtual int DefaultNodesHeight { get { return 18; } }
    public class MyTreeListNode : TreeListNode {
        const int minHeight = 5;
        int height;
        public MyTreeListNode(int id, TreeListNodes owner) : base(id, owner) {
            this.height = (owner.TreeList as MyTreeList).DefaultNodesHeight;
        public int Height {
            get { return height; }
            set {
                if (Height == value || value < minHeight) return;
                height = value;

    public class MyRecord {
        public int ID { get; set; }
        public int ParentID { get; set; }

        public string Department { get; set; }
        public string Location { get; set; }
        public decimal Budget { get; set; }

        public MyRecord(int id, int parentID, string department, decimal budget, string location) {
            ID = id;
            ParentID = parentID;
            Department = department;
            Budget = budget;
            Location = location;