windowsforms-5597-controls-and-libraries-tree-list-feature-center-nodes-custom-nodes.md
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.
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:
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.
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() {
InitializeComponent();
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) {
treeList1.ForceInitialize();
treeList1.ExpandAll();
((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)
LayoutChanged();
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;
else
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;
Changed(NodeChangeTypeEnum.User1);
}
}
}
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;
}
}
}
Imports DevExpress.XtraTreeList
Imports DevExpress.XtraTreeList.Nodes
Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Data
Imports System.Drawing
Imports System.Linq
Imports System.Text
Imports System.Threading.Tasks
Imports System.Windows.Forms
Namespace CustomTreeList_NodeHeight
Partial Public Class Form1
Inherits Form
Public Sub New()
InitializeComponent()
Dim list As New List(Of 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"
End Sub
Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) Handles MyBase.Load
treeList1.ForceInitialize()
treeList1.ExpandAll()
CType(treeList1.Nodes(0), MyTreeListNode).Height = 35
CType(treeList1.Nodes(0).Nodes(1), MyTreeListNode).Height = 35
End Sub
End Class
Public Class MyTreeList
Inherits TreeList
Public Sub New()
MyBase.New()
OptionsBehavior.AutoNodeHeight = False
End Sub
Protected Overrides Function CreateNode(ByVal nodeID As Integer, ByVal owner As TreeListNodes, ByVal tag As Object) As TreeListNode
Return New MyTreeListNode(nodeID, owner)
End Function
Protected Overrides Sub InternalNodeChanged(ByVal node As TreeListNode, ByVal nodes As TreeListNodes, ByVal changeType As NodeChangeTypeEnum)
If changeType = NodeChangeTypeEnum.User1 Then
LayoutChanged()
End If
MyBase.InternalNodeChanged(node, nodes, changeType)
End Sub
Protected Overrides Sub RaiseCalcNodeHeight(ByVal node As TreeListNode, ByRef nodeHeight As Integer)
Dim myNode As MyTreeListNode = CType(node, MyTreeListNode)
If Not myNode Is Nothing Then
nodeHeight = myNode.Height
Else
MyBase.RaiseCalcNodeHeight(node, nodeHeight)
End If
End Sub
Public Overridable ReadOnly Property DefaultNodesHeight() As Integer
Get
Return 18
End Get
End Property
End Class
Public Class MyTreeListNode
Inherits TreeListNode
Const minHeight As Integer = 5
Dim fHeight As Integer
Public Sub New(ByVal id As Integer, ByVal owner As TreeListNodes)
MyBase.New(id, owner)
Me.fHeight = CType(owner.TreeList, MyTreeList).DefaultNodesHeight
End Sub
Public Property Height() As Integer
Get
Return fHeight
End Get
Set(ByVal Value As Integer)
If fHeight = Value Or Value < minHeight Then Return
fHeight = Value
Changed(NodeChangeTypeEnum.User1)
End Set
End Property
End Class
Public Class MyRecord
Public Property ID() As Integer
Public Property ParentID() As Integer
Public Property Department() As String
Public Property Location() As String
Public Property Budget() As Decimal
Public Sub New(ByVal id As Integer, ByVal parentID As Integer, ByVal department As String, ByVal budget As Decimal, ByVal location As String)
Me.ID = id
Me.ParentID = parentID
Me.Department = department
Me.Budget = budget
Me.Location = location
End Sub
End Class
End Namespace