windowsforms-devexpress-dot-xtratreelist-dot-treelist-aab264d4.md
Allows you to provide data to unbound columns, and save their modified records to an external source.
Namespace : DevExpress.XtraTreeList
Assembly : DevExpress.XtraTreeList.v25.2.dll
NuGet Packages : DevExpress.Win.Navigation, DevExpress.Win.TreeList
[DXCategory("Behavior")]
public event CustomColumnDataEventHandler CustomUnboundColumnData
<DXCategory("Behavior")>
Public Event CustomUnboundColumnData As CustomColumnDataEventHandler
The CustomUnboundColumnData event's data class is DevExpress.XtraTreeList.TreeListCustomColumnDataEventArgs.
Unbound columns are not bound to any field in the underlying data source. Data for these columns can be provided either by creating an expression using the TreeListColumn.UnboundExpression property or by handling the CustomUnboundColumnData event. To learn about the syntax of expressions, see Expressions.
You can create an unbound (calculated) column as follows:
The CustomUnboundColumnData event fires only for visible unbound columns. It fires in two cases:
Your CustomUnboundColumnData event handler must not dispose of the control’s data source, modify column settings, the control’s layout and object model.
Note
The CustomUnboundColumnData event is not raised if the TreeList.DataSource property equals null.
Note
The CustomUnboundColumnData event fires for each cell. However, due to the treelist control’s data processing algorithms, this event may fire repeatedly, multiple times, for each cell. The treelist control doesn’t cache data you provided via the CustomUnboundColumnData event. If providing data via the event takes considerable time, you need to manually cache data.
This example demonstrates how to create an editable unbound column. The example uses a simple cache implementation within the CustomUnboundColumnData event handler to fetch custom data faster.
using DevExpress.XtraTreeList.Columns;
private void CreateUnboundColumn() {
TreeListColumn column = treeList1.Columns.AddVisible("UnboundColumn");
column.UnboundDataType = typeof(string);
}
Dictionary<int, string> storage = new Dictionary<int, string>();
private void treeList1_CustomUnboundColumnData(object sender, DevExpress.XtraTreeList.TreeListCustomColumnDataEventArgs e) {
if(e.Column.FieldName == "UnboundColumn") {
if(e.IsGetData)
if(storage.ContainsKey(e.NodeID))
e.Value = storage[e.NodeID];
else
e.Value = storage[e.NodeID] = string.Format("Unbound value {0}", e.NodeID);
if(e.IsSetData)
storage[e.NodeID] = e.Value.ToString();
}
}
Imports DevExpress.XtraTreeList.Columns
Private Sub CreateUnboundColumn()
Dim column As TreeListColumn = treeList1.Columns.AddVisible("UnboundColumn")
column.UnboundDataType = GetType(String)
End Sub
Private storage As New Dictionary(Of Integer, String)()
Private Sub treeList1_CustomUnboundColumnData(ByVal sender As Object, ByVal e As DevExpress.XtraTreeList.TreeListCustomColumnDataEventArgs)
If e.Column.FieldName = "UnboundColumn" Then
If e.IsGetData Then
If storage.ContainsKey(e.NodeID) Then
e.Value = storage(e.NodeID)
Else
storage(e.NodeID) = String.Format("Unbound value {0}", e.NodeID)
e.Value = storage(e.NodeID)
End If
End If
If e.IsSetData Then
storage(e.NodeID) = e.Value.ToString()
End If
End If
End Sub
This example creates a “Change from Previous Year” read-only unbound column in the TreeList control and populates this column with data using the TreeList.CustomUnboundColumnData event.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using DevExpress.Skins;
using DevExpress.LookAndFeel;
using DevExpress.UserSkins;
using DevExpress.XtraTreeList.Columns;
namespace TreeList_UnboundDataViaEvent {
public partial class Form1 : XtraForm {
public Form1() {
InitializeComponent();
InitTreeList();
}
void InitTreeList() {
treeList1.DataSource = SalesDataGenerator.CreateData();
// Create and customize an unbound column.
TreeListColumn unbColumnMarchChange = new TreeListColumn();
unbColumnMarchChange.UnboundDataType = typeof(decimal);
unbColumnMarchChange.Visible = true;
unbColumnMarchChange.OptionsColumn.AllowEdit = false;
unbColumnMarchChange.FieldName = "ChangeFromPrevYear";
unbColumnMarchChange.Caption = "Change from Previous Year";
unbColumnMarchChange.Format.FormatType = DevExpress.Utils.FormatType.Numeric;
unbColumnMarchChange.Format.FormatString = "p2";
tlBandThisYear.Columns.Add(unbColumnMarchChange);
// Change the appearance settings after the column is added to the TreeList.
unbColumnMarchChange.AppearanceHeader.Font = new Font(unbColumnMarchChange.AppearanceHeader.Font, FontStyle.Bold);
unbColumnMarchChange.AppearanceCell.BackColor = Color.LightYellow;
// Subcribe to the event that provides data for unbound columns.
treeList1.CustomUnboundColumnData += TreeList1_CustomUnboundColumnData;
// Resize columns proportionally.
treeList1.ForceInitialize();
treeList1.BestFitColumns();
}
private void TreeList1_CustomUnboundColumnData(object sender, DevExpress.XtraTreeList.TreeListCustomColumnDataEventArgs e) {
if(e.IsGetData && e.Column.FieldName == "ChangeFromPrevYear") {
SalesData currentRow = e.Row as SalesData;
if (currentRow == null) return;
e.Value = (currentRow.MarchSales - currentRow.MarchSalesPrev) / currentRow.MarchSalesPrev;
}
}
}
public class SalesData {
public SalesData(int id, int regionId, string region, decimal marchSales, decimal marchSalesPrev) {
ID = id;
RegionID = regionId;
Region = region;
MarchSales = marchSales;
MarchSalesPrev = marchSalesPrev;
}
public int ID { get; set; }
public int RegionID { get; set; }
public string Region { get; set; }
public decimal MarchSales { get; set; }
public decimal MarchSalesPrev { get; set; }
}
public class SalesDataGenerator {
public static List<SalesData> CreateData() {
List<SalesData> sales = new List<SalesData>();
sales.Add(new SalesData(0, -1, "Western Europe", 30540, 33000));
sales.Add(new SalesData(1, 0, "Austria", 22000, 20000));
sales.Add(new SalesData(2, 0, "Belgium", 13000, 9640));
sales.Add(new SalesData(3, 0, "Denmark", 21000, 18100));
sales.Add(new SalesData(4, 0, "Finland", 17000, 17420));
sales.Add(new SalesData(5, 0, "France", 23020, 27000));
sales.Add(new SalesData(6, 0, "Germany", 30540, 33000));
sales.Add(new SalesData(7, 0, "Greece", 15600, 13200));
sales.Add(new SalesData(8, 0, "Ireland", 9530, 10939));
sales.Add(new SalesData(9, 0, "Italy", 17299, 19321));
sales.Add(new SalesData(11, 0, "Netherlands", 8902, 9214));
sales.Add(new SalesData(12, 0, "Norway", 5400, 7310));
sales.Add(new SalesData(13, 0, "Portugal", 9220, 4271));
sales.Add(new SalesData(14, 0, "Spain", 12900, 10300));
sales.Add(new SalesData(15, 0, "Switzerland", 9323, 10730));
sales.Add(new SalesData(16, 0, "United Kingdom", 14580, 13967));
sales.Add(new SalesData(17, -1, "Eastern Europe", 22500, 24580));
sales.Add(new SalesData(18, 17, "Belarus", 7315, 18800));
sales.Add(new SalesData(19, 17, "Bulgaria", 6300, 2821));
sales.Add(new SalesData(20, 17, "Croatia", 4200, 3890));
sales.Add(new SalesData(21, 17, "Czech Republic", 19500, 15340));
sales.Add(new SalesData(22, 17, "Hungary", 13495, 13900));
sales.Add(new SalesData(23, 17, "Poland", 8930, 9440));
sales.Add(new SalesData(24, 17, "Romania", 4900, 5100));
sales.Add(new SalesData(25, 17, "Russia", 22500, 24580));
sales.Add(new SalesData(26, -1, "North America", 31400, 32800));
sales.Add(new SalesData(27, 26, "USA", 31400, 32800));
sales.Add(new SalesData(28, 26, "Canada", 25390, 27000));
sales.Add(new SalesData(29, -1, "South America", 16380, 15590));
sales.Add(new SalesData(30, 29, "Argentina", 16380, 15590));
sales.Add(new SalesData(31, 29, "Brazil", 4560, 5480));
sales.Add(new SalesData(32, -1, "Asia", 20388, 22547));
sales.Add(new SalesData(34, 32, "India", 4642, 5320));
sales.Add(new SalesData(35, 32, "Japan", 9457, 12859));
sales.Add(new SalesData(36, 32, "China", 20388, 22547));
return sales;
}
}
}
Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Data
Imports System.Drawing
Imports System.Linq
Imports System.Text
Imports System.Windows.Forms
Imports DevExpress.XtraEditors
Imports DevExpress.Skins
Imports DevExpress.LookAndFeel
Imports DevExpress.UserSkins
Imports DevExpress.XtraTreeList.Columns
Namespace TreeList_UnboundDataViaEvent
Partial Public Class Form1
Inherits XtraForm
Public Sub New()
InitializeComponent()
InitTreeList()
End Sub
Private Sub InitTreeList()
treeList1.DataSource = SalesDataGenerator.CreateData()
' Create and customize an unbound column.
Dim unbColumnMarchChange As New TreeListColumn()
unbColumnMarchChange.UnboundDataType = GetType(Decimal)
unbColumnMarchChange.Visible = True
unbColumnMarchChange.OptionsColumn.AllowEdit = False
unbColumnMarchChange.FieldName = "ChangeFromPrevYear"
unbColumnMarchChange.Caption = "Change from Previous Year"
unbColumnMarchChange.Format.FormatType = DevExpress.Utils.FormatType.Numeric
unbColumnMarchChange.Format.FormatString = "p2"
tlBandThisYear.Columns.Add(unbColumnMarchChange)
' Change the appearance settings after the column is added to the TreeList.
unbColumnMarchChange.AppearanceHeader.Font = New Font(unbColumnMarchChange.AppearanceHeader.Font, FontStyle.Bold)
unbColumnMarchChange.AppearanceCell.BackColor = Color.LightYellow
' Subcribe to the event that provides data for unbound columns.
AddHandler treeList1.CustomUnboundColumnData, AddressOf TreeList1_CustomUnboundColumnData
' Resize columns proportionally.
treeList1.ForceInitialize()
treeList1.BestFitColumns()
End Sub
Private Sub TreeList1_CustomUnboundColumnData(ByVal sender As Object, ByVal e As DevExpress.XtraTreeList.TreeListCustomColumnDataEventArgs)
If e.IsGetData AndAlso e.Column.FieldName = "ChangeFromPrevYear" Then
Dim currentRow As SalesData = TryCast(e.Row, SalesData)
If currentRow Is Nothing Then
Return
End If
e.Value = (currentRow.MarchSales - currentRow.MarchSalesPrev) / currentRow.MarchSalesPrev
End If
End Sub
End Class
Public Class SalesData
Public Sub New(ByVal id As Integer, ByVal regionId As Integer, ByVal region As String, ByVal marchSales As Decimal, ByVal marchSalesPrev As Decimal)
Me.ID = id
Me.RegionID = regionId
Me.Region = region
Me.MarchSales = marchSales
Me.MarchSalesPrev = marchSalesPrev
End Sub
Public Property ID() As Integer
Public Property RegionID() As Integer
Public Property Region() As String
Public Property MarchSales() As Decimal
Public Property MarchSalesPrev() As Decimal
End Class
Public Class SalesDataGenerator
Public Shared Function CreateData() As List(Of SalesData)
Dim sales As New List(Of SalesData)()
sales.Add(New SalesData(0, -1, "Western Europe", 30540, 33000))
sales.Add(New SalesData(1, 0, "Austria", 22000, 20000))
sales.Add(New SalesData(2, 0, "Belgium", 13000, 9640))
sales.Add(New SalesData(3, 0, "Denmark", 21000, 18100))
sales.Add(New SalesData(4, 0, "Finland", 17000, 17420))
sales.Add(New SalesData(5, 0, "France", 23020, 27000))
sales.Add(New SalesData(6, 0, "Germany", 30540, 33000))
sales.Add(New SalesData(7, 0, "Greece", 15600, 13200))
sales.Add(New SalesData(8, 0, "Ireland", 9530, 10939))
sales.Add(New SalesData(9, 0, "Italy", 17299, 19321))
sales.Add(New SalesData(11, 0, "Netherlands", 8902, 9214))
sales.Add(New SalesData(12, 0, "Norway", 5400, 7310))
sales.Add(New SalesData(13, 0, "Portugal", 9220, 4271))
sales.Add(New SalesData(14, 0, "Spain", 12900, 10300))
sales.Add(New SalesData(15, 0, "Switzerland", 9323, 10730))
sales.Add(New SalesData(16, 0, "United Kingdom", 14580, 13967))
sales.Add(New SalesData(17, -1, "Eastern Europe", 22500, 24580))
sales.Add(New SalesData(18, 17, "Belarus", 7315, 18800))
sales.Add(New SalesData(19, 17, "Bulgaria", 6300, 2821))
sales.Add(New SalesData(20, 17, "Croatia", 4200, 3890))
sales.Add(New SalesData(21, 17, "Czech Republic", 19500, 15340))
sales.Add(New SalesData(22, 17, "Hungary", 13495, 13900))
sales.Add(New SalesData(23, 17, "Poland", 8930, 9440))
sales.Add(New SalesData(24, 17, "Romania", 4900, 5100))
sales.Add(New SalesData(25, 17, "Russia", 22500, 24580))
sales.Add(New SalesData(26, -1, "North America", 31400, 32800))
sales.Add(New SalesData(27, 26, "USA", 31400, 32800))
sales.Add(New SalesData(28, 26, "Canada", 25390, 27000))
sales.Add(New SalesData(29, -1, "South America", 16380, 15590))
sales.Add(New SalesData(30, 29, "Argentina", 16380, 15590))
sales.Add(New SalesData(31, 29, "Brazil", 4560, 5480))
sales.Add(New SalesData(32, -1, "Asia", 20388, 22547))
sales.Add(New SalesData(34, 32, "India", 4642, 5320))
sales.Add(New SalesData(35, 32, "Japan", 9457, 12859))
sales.Add(New SalesData(36, 32, "China", 20388, 22547))
Return sales
End Function
End Class
End Namespace
The following code snippet (auto-collected from DevExpress Examples) contains a reference to the CustomUnboundColumnData event.
Note
The algorithm used to collect these code examples remains a work in progress. Accordingly, the links and snippets below may produce inaccurate results. If you encounter an issue with code examples below, please use the feedback form on this page to report the issue.
winforms-treelist-unbound-columns/CS/TreeList_UnboundDataViaEvent/Form1.cs#L39
// Subcribe to the event that provides data for unbound columns.
treeList1.CustomUnboundColumnData += TreeList1_CustomUnboundColumnData;
// Resize columns proportionally.
winforms-treelist-unbound-columns/VB/TreeList_UnboundDataViaEvent/Form1.vb#L34
' Subcribe to the event that provides data for unbound columns.
AddHandler treeList1.CustomUnboundColumnData, AddressOf TreeList1_CustomUnboundColumnData
' Resize columns proportionally.
See Also