Back to Devexpress

TreeList.CustomUnboundColumnData Event

windowsforms-devexpress-dot-xtratreelist-dot-treelist-aab264d4.md

latest19.1 KB
Original Source

TreeList.CustomUnboundColumnData Event

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

Declaration

csharp
[DXCategory("Behavior")]
public event CustomColumnDataEventHandler CustomUnboundColumnData
vb
<DXCategory("Behavior")>
Public Event CustomUnboundColumnData As CustomColumnDataEventHandler

Event Data

The CustomUnboundColumnData event's data class is DevExpress.XtraTreeList.TreeListCustomColumnDataEventArgs.

Remarks

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:

  1. Create a TreeListColumn object and add it to the TreeList.Columns collection.
  2. Set the column’s TreeListColumn.UnboundDataType property to the type of data the column is supposed to display.
  3. Set the column’s TreeListColumn.FieldName to a unique value.

The CustomUnboundColumnData event fires only for visible unbound columns. It fires in two cases:

  • When the treelist is loaded, it raises the CustomUnboundColumnData event to populate the unbound columns. The event’s IsGetData parameter will be set to true (consequently the IsSetData parameter will be set to false ). In this case, you need to supply data for the currently processed cell. Obtain the required value from a custom data source, and assign it to the Value parameter.
  • When an unbound column’s data is modified from the treelist, the CustomUnboundColumnData event is fired with the IsSetData parameter set to true (consequently the IsGetData parameter is set to false ). In this case, you should save the modified data specified by the Value property back to the data source.

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.

Example 1

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.

csharp
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();
    }
}
vb
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

Example 2

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.

View Example

csharp
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;
        }
    }

}
vb
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

csharp
// 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

vb
' Subcribe to the event that provides data for unbound columns.
AddHandler treeList1.CustomUnboundColumnData, AddressOf TreeList1_CustomUnboundColumnData
' Resize columns proportionally.

See Also

UnboundExpression

UnboundDataType

Columns

Unbound Columns

TreeList Class

TreeList Members

DevExpress.XtraTreeList Namespace