Nodes > Custom Nodes |
TreeView allows creating and displaying custom nodes in place of the default nodes. It is possible to add custom properties and show various customizations, for instance, including, scaling, and aligning images, displaying borders, customizing font styles and colors, and changing dimensions etc. To set custom nodes in TreeView, set the CustomContentPresenter property of C1TreeColumn.
The following image displays custom nodes in TreeView.
To create custom nodes in TreeView, create custom classes to define properties and methods that apply to custom nodes and override the default ones. After creating custom classes, initialize their instances and set custom nodes using the CustomContentPresenter property.
The following code snippets show how to create custom classes to define main elements for custom nodes.
Public Class CategoryCustomNode Inherits CustomContentPresenter ' level 0 Private _name As TextElement Private _description As TextElement Private _img As ImageElement Private _rw As RowPanel ' level 1 Private _product As TextElement Public Sub New() ' level 0 ' init text elements ' name _name = New TextElement() _name.Style = New Style() ' description _description = New TextElement() _description.Style = New Style() _description.Width = 120 ' init image element _img = New ImageElement() _img.Style = New Style() _img.Size = New Size(70, 50) ' init a grid for text elements Dim cp = New ColumnPanel() cp.Children.Add(_name) cp.Children.Add(_description) ' init panel for image _rw = New RowPanel() _rw.Children.Add(cp) _rw.Children.Add(_img) _rw.Style = New Style() _rw.Style.VerticalAlignment = Alignment.Center ' level 1 _product = New TextElement() _product.Style = New Style() End Sub Public Overrides ReadOnly Property ToolTipText() As String Get Return _name.Text End Get End Property Public Overrides Sub SetStyle(styles As TreeNodeCellStyles) ' level 0 ' name _name.Style.Margins = New Thickness(1) _name.Style.Font = New Font("Calibri", 10, FontStyle.Bold) ' description _description.Style.Margins = New Thickness(1) _description.Style.Font = New Font("Calibri", 9, FontStyle.Italic) _description.Style.WordWrap = True ' img _img.Style.ImageScaling = ImageScaling.Scale _img.Style.ImageAlignment = ImageAlignment.CenterCenter ' level 1 _product.Style.Font = New Font("Calibri", 10, FontStyle.Bold) _product.Style.Margins = New Thickness(2) _product.Style.HorizontalAlignment = Alignment.Center _product.Style.VerticalAlignment = Alignment.Center End Sub Public Overrides Sub SetValue(value As Object) If Node.Level = 0 Then Dim row = DirectCast(Node.GetValue(), DataSet1.CategoriesRow) _name.Text = row.CategoryName _description.Text = row.Description Dim converter = New ImageConverter() If _img.Image IsNot Nothing Then _img.Image.Dispose() _img.Image = Nothing End If _img.Image = DirectCast(converter.ConvertFrom(row.Picture), Image) ' set root panel Child = _rw Else _product.Text = value.ToString() ' set root element Child = _product End If End Sub End Class Public Class ProductCustomNode Inherits CustomContentPresenter ' level 0 Private _count As TextElement ' level 1 Private _quantityPerUnit As TextElement Private _unitPrice As TextElement Private _unitInStock As TextElement Private _unitsOnOrder As TextElement Private _reorderLevel As TextElement Private _gp As GridPanel Private _eStyle As Style Public Sub New() ' level 0 ' count in category _count = New TextElement() _count.Style = New Style() _count.Style.Margins = New Thickness(2) ' level 1 ' lable style Dim lStyle = New Style() lStyle.HorizontalAlignment = Alignment.Far lStyle.Margins = New Thickness(1) lStyle.Font = New Font("Calibri", 9, FontStyle.Regular) ' elements style _eStyle = New Style() _eStyle.Margins = New Thickness(1) _eStyle.Font = New Font("Calibri", 9, FontStyle.Regular) ' init elements _quantityPerUnit = New TextElement(_eStyle.Clone()) _unitPrice = New TextElement(_eStyle.Clone()) _unitInStock = New TextElement(_eStyle.Clone()) _unitsOnOrder = New TextElement(_eStyle.Clone()) _reorderLevel = New TextElement(_eStyle.Clone()) ' init a grid for text elements _gp = New GridPanel() _gp.Columns.Add() ' labels _gp.Columns(0).Width = 100 _gp.Columns.Add() ' text _gp.Columns(1).Width = 120 _gp.Rows.Add() ' ReorderLevel _gp(0, 0).Element = New TextElement(lStyle, "Reorder level:") _gp(0, 1).Element = _reorderLevel _gp.Rows.Add() ' UnitPrice _gp(1, 0).Element = New TextElement(lStyle, "Unit price:") _gp(1, 1).Element = _unitPrice _gp.Rows.Add() ' QuantityPerUnit _gp(2, 0).Element = New TextElement(lStyle, "Quantity per unit:") _gp(2, 1).Element = _quantityPerUnit _gp.Columns.Add() ' labels _gp.Columns(2).Width = 100 _gp.Columns.Add() ' text ' UnitsInStock _gp(0, 2).Element = New TextElement(lStyle, "Units in stock:") _gp(0, 3).Element = _unitInStock ' UnitsOnOrder _gp(1, 2).Element = New TextElement(lStyle, "Units on order:") _gp(1, 3).Element = _unitsOnOrder End Sub Public Overrides ReadOnly Property ToolTipText() As String Get Return String.Empty End Get End Property Public Overrides Sub SetStyle(styles As TreeNodeCellStyles) ' level 0 _count.Style.HorizontalAlignment = Alignment.Center _count.Style.VerticalAlignment = Alignment.Center _count.Style.Font = New Font("Calibri", 11, FontStyle.Bold) ' level 1 _unitPrice.Style.Font = New Font(_eStyle.Font, FontStyle.Bold) If _unitInStock.Text = "0" Then _unitInStock.Style.ForeColor = Color.Red _unitInStock.Style.Font = New Font(_eStyle.Font, FontStyle.Bold) End If If _unitsOnOrder.Text = "0" Then _unitsOnOrder.Style.ForeColor = Color.Red _unitsOnOrder.Style.Font = New Font(_eStyle.Font, FontStyle.Bold) End If End Sub Public Overrides Sub SetValue(value As Object) If Node.Level = 0 Then Dim count = If(Node.HasChildren, Node.Nodes.Count, 0) _count.Text = count.ToString() Child = _count Else Dim row = DirectCast(Node.GetValue(), DataSet1.ProductsRow) _quantityPerUnit.Text = row.QuantityPerUnit _unitPrice.Text = row.UnitPrice.ToString("C") _unitInStock.Text = row.UnitsInStock.ToString() _unitsOnOrder.Text = row.UnitsOnOrder.ToString() _reorderLevel.Text = row.ReorderLevel.ToString() Child = _gp End If End Sub End Class
public class CategoryCustomNode : CustomContentPresenter { // level 0 private TextElement _name; private TextElement _description; private ImageElement _img; private RowPanel _rw; // level 1 private TextElement _product; public CategoryCustomNode() { // level 0 // init text elements // name _name = new TextElement(); _name.Style = new Style(); // description _description = new TextElement(); _description.Style = new Style(); _description.Width = 120; // init image element _img = new ImageElement(); _img.Style = new Style(); _img.Size = new Size(70, 50); // init a grid for text elements var cp = new ColumnPanel(); cp.Children.Add(_name); cp.Children.Add(_description); // init panel for image _rw = new RowPanel(); _rw.Children.Add(cp); _rw.Children.Add(_img); _rw.Style = new Style(); _rw.Style.VerticalAlignment = Alignment.Center; // level 1 _product = new TextElement(); _product.Style = new Style(); } public override string ToolTipText { get { return _name.Text; } } public override void SetStyle(TreeNodeCellStyles styles) { // level 0 // name _name.Style.Margins = new Thickness(1); _name.Style.Font = new Font("Calibri", 10, FontStyle.Bold); // description _description.Style.Margins = new Thickness(1); _description.Style.Font = new Font("Calibri", 9, FontStyle.Italic); _description.Style.WordWrap = true; // img _img.Style.ImageScaling = ImageScaling.Scale; _img.Style.ImageAlignment = ImageAlignment.CenterCenter; // level 1 _product.Style.Font = new Font("Calibri", 10, FontStyle.Bold); _product.Style.Margins = new Thickness(2); _product.Style.HorizontalAlignment = Alignment.Center; _product.Style.VerticalAlignment = Alignment.Center; } public override void SetValue(object value) { if (Node.Level == 0) { var row = (DataSet1.CategoriesRow)Node.GetValue(); _name.Text = row.CategoryName; _description.Text = row.Description; var converter = new ImageConverter(); if (_img.Image != null) { _img.Image.Dispose(); _img.Image = null; } _img.Image = (Image)converter.ConvertFrom(row.Picture); // set root panel Child = _rw; } else { _product.Text = value.ToString(); // set root element Child = _product; } } } public class ProductCustomNode : CustomContentPresenter { // level 0 private TextElement _count; // level 1 private TextElement _quantityPerUnit; private TextElement _unitPrice; private TextElement _unitInStock; private TextElement _unitsOnOrder; private TextElement _reorderLevel; private GridPanel _gp; private Style _eStyle; public ProductCustomNode() { // level 0 // count in category _count = new TextElement(); _count.Style = new Style(); _count.Style.Margins = new Thickness(2); // level 1 // lable style var lStyle = new Style(); lStyle.HorizontalAlignment = Alignment.Far; lStyle.Margins = new Thickness(1); lStyle.Font = new Font("Calibri", 9, FontStyle.Regular); // elements style _eStyle = new Style(); _eStyle.Margins = new Thickness(1); _eStyle.Font = new Font("Calibri", 9, FontStyle.Regular); // init elements _quantityPerUnit = new TextElement(_eStyle.Clone()); _unitPrice = new TextElement(_eStyle.Clone()); _unitInStock = new TextElement(_eStyle.Clone()); _unitsOnOrder = new TextElement(_eStyle.Clone()); _reorderLevel = new TextElement(_eStyle.Clone()); // init a grid for text elements _gp = new GridPanel(); _gp.Columns.Add(); // labels _gp.Columns[0].Width = 100; _gp.Columns.Add(); // text _gp.Columns[1].Width = 120; _gp.Rows.Add(); // ReorderLevel _gp[0, 0].Element = new TextElement(lStyle, "Reorder level:"); _gp[0, 1].Element = _reorderLevel; _gp.Rows.Add(); // UnitPrice _gp[1, 0].Element = new TextElement(lStyle, "Unit price:"); _gp[1, 1].Element = _unitPrice; _gp.Rows.Add(); // QuantityPerUnit _gp[2, 0].Element = new TextElement(lStyle, "Quantity per unit:"); _gp[2, 1].Element = _quantityPerUnit; _gp.Columns.Add(); // labels _gp.Columns[2].Width = 100; _gp.Columns.Add(); // text // UnitsInStock _gp[0, 2].Element = new TextElement(lStyle, "Units in stock:"); _gp[0, 3].Element = _unitInStock; // UnitsOnOrder _gp[1, 2].Element = new TextElement(lStyle, "Units on order:"); _gp[1, 3].Element = _unitsOnOrder; } public override string ToolTipText { get { return string.Empty; ; } } public override void SetStyle(TreeNodeCellStyles styles) { // level 0 _count.Style.HorizontalAlignment = Alignment.Center; _count.Style.VerticalAlignment = Alignment.Center; _count.Style.Font = new Font("Calibri", 11, FontStyle.Bold); // level 1 _unitPrice.Style.Font = new Font(_eStyle.Font, FontStyle.Bold); if (_unitInStock.Text == "0") { _unitInStock.Style.ForeColor = Color.Red; _unitInStock.Style.Font = new Font(_eStyle.Font, FontStyle.Bold); } if (_unitsOnOrder.Text == "0") { _unitsOnOrder.Style.ForeColor = Color.Red; _unitsOnOrder.Style.Font = new Font(_eStyle.Font, FontStyle.Bold); } } public override void SetValue(object value) { if (Node.Level == 0) { var count = Node.HasChildren ? Node.Nodes.Count : 0; _count.Text = count.ToString(); Child = _count; } else { var row = (DataSet1.ProductsRow)Node.GetValue(); _quantityPerUnit.Text = row.QuantityPerUnit; _unitPrice.Text = row.UnitPrice.ToString("C"); _unitInStock.Text = row.UnitsInStock.ToString(); _unitsOnOrder.Text = row.UnitsOnOrder.ToString(); _reorderLevel.Text = row.ReorderLevel.ToString(); Child = _gp; } } }
The following code snippet shows how to set custom nodes using the CustomContentPresenter property.
' set custom nodes C1TreeView1.Columns(0).CustomContentPresenter = New CategoryCustomNode() C1TreeView1.Columns(1).CustomContentPresenter = New ProductCustomNode()
// set custom nodes c1TreeView1.Columns[0].CustomContentPresenter = new CategoryCustomNode(); c1TreeView1.Columns[1].CustomContentPresenter = new ProductCustomNode();