The event handler receives an argument of type CustomColumnDataEventArgs containing data related to this event.
The following
CustomColumnDataEventArgs properties provide information specific to this event.
Property |
Description |
Column |
Gets the unbound column currently being processed. |
IsGetData |
Gets a Boolean value which indicates whether you should provide data for the currently processed cell. |
IsSetData |
Gets whether the current cell's value should be stored in a custom data source. |
ListSourceRowIndex |
Gets the current row's index in the data source. |
Row |
Gets the currently processed row. |
Value |
Gets or sets the value of the cell currently being processed. |
The CustomUnboundColumnData event fires only for visible unbound columns. It fires in two cases:
-
when the Grid Control is loaded, it raises the CustomUnboundColumnData event to populate unbound columns. The event's IsGetData parameter returns true, the IsSetData parameter returns false. Assign a custom value for the currently processed cell to the event's Value parameter.
-
when a user changes an unbound column cell data. In this case, the event's IsSetData parameter returns true , and the IsGetData parameter returns false. Read the Value parameter to get the modified cell value, and save this value to a source.
For a column that owns the currently processed cell, use the CustomColumnDataEventArgs.Column parameter. To identify the row, use the CustomColumnDataEventArgs.ListSourceRowIndex or CustomColumnDataEventArgs.Row parameters.
Note
If you need to get or set specific cell values while handling the CustomUnboundColumnData event, use methods provided by the bound data source. The event's Row and ListSourceRowIndex parameters allow you to identify the current data row. To get values in a specific row in the data source, you can use the GetListSourceRowCellValue method or methods provided by row objects.
Note
The CustomUnboundColumnData event fires for each cell. However, due to the Grid control's data processing algorithms, this event may fire multiple times for each cell. The grid control does not cache data you provide on the CustomUnboundColumnData event. If these data operations take too long, you need to manually cache data.
This event allows you to provide cell values only. Do not try to modify column settings in the CustomUnboundCOlumnData event handler.
Note
Server Mode does not support sorting, grouping, filtering and summary calculation for unbound columns that receive cell values on the CustomUnboundColumnData event. These features are still supported for unbound columns that are populated with expressions (see GridColumn.UnboundExpression).
Refer to the Unbound Columns document for more information.

Example 1
Assume that the Grid Control is bound to a table that contains the "Quantity", "UnitPrice" and "Discount" columns. The example below shows how to add an unbound column to the grid to display the amount of each order according to the expression: QuantityUnitPrice(1-Discount).
The result is displayed below:

For another example which illustrates working with unbound columns, see the Unbound Columns tutorial.
C# |
using DevExpress.XtraGrid.Views.Base;
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraGrid.Columns;
private void Form1_Load(object sender, System.EventArgs e) {
gridControl1.ForceInitialize();
GridColumn unbColumn = gridView1.Columns.AddField("Total");
unbColumn.VisibleIndex = gridView1.Columns.Count;
unbColumn.UnboundType = DevExpress.Data.UnboundColumnType.Decimal;
unbColumn.OptionsColumn.AllowEdit = false;
unbColumn.DisplayFormat.FormatType = DevExpress.Utils.FormatType.Numeric;
unbColumn.DisplayFormat.FormatString = "c";
unbColumn.AppearanceCell.BackColor = Color.LemonChiffon;
}
decimal getTotalValue(GridView view, int listSourceRowIndex) {
decimal unitPrice = Convert.ToDecimal(view.GetListSourceRowCellValue(listSourceRowIndex, "UnitPrice"));
decimal quantity = Convert.ToDecimal(view.GetListSourceRowCellValue(listSourceRowIndex, "Quantity"));
decimal discount = Convert.ToDecimal(view.GetListSourceRowCellValue(listSourceRowIndex, "Discount"));
return unitPrice * quantity * (1 - discount);
}
private void gridView1_CustomUnboundColumnData(object sender, CustomColumnDataEventArgs e) {
GridView view = sender as GridView;
if (e.Column.FieldName == "Total" && e.IsGetData) e.Value =
getTotalValue(view, e.ListSourceRowIndex);
}
|
VB |
Imports DevExpress.XtraGrid.Views.Base
Imports DevExpress.XtraGrid.Views.Grid
Imports DevExpress.XtraGrid.Columns
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
gridControl1.ForceInitialize()
Dim unbColumn As GridColumn = GridView1.Columns.AddField("Total")
unbColumn.VisibleIndex = GridView1.Columns.Count
unbColumn.UnboundType = DevExpress.Data.UnboundColumnType.Decimal
unbColumn.OptionsColumn.AllowEdit = False
unbColumn.DisplayFormat.FormatType = DevExpress.Utils.FormatType.Numeric
unbColumn.DisplayFormat.FormatString = "c"
unbColumn.AppearanceCell.BackColor = Color.LemonChiffon
End Sub
Private Function getTotalValue(view As GridView, listSourceRowIndex As Integer) As Decimal
Dim unitPrice As Decimal = Convert.ToDecimal(view.GetListSourceRowCellValue(listSourceRowIndex, "UnitPrice"))
Dim quantity As Decimal = Convert.ToDecimal(view.GetListSourceRowCellValue(listSourceRowIndex, "Quantity"))
Dim discount As Decimal = Convert.ToDecimal(view.GetListSourceRowCellValue(listSourceRowIndex, "Discount"))
Return unitPrice * quantity * (1 - discount)
End Function
Private Sub GridView1_CustomUnboundColumnData(ByVal sender As Object, _
ByVal e As CustomColumnDataEventArgs) Handles GridView1.CustomUnboundColumnData
Dim view As GridView = TryCast(sender, GridView)
If e.Column.FieldName = "Total" AndAlso e.IsGetData Then
e.Value = getTotalValue(view, e.ListSourceRowIndex)
End If
End Sub
|

Example 2
GridView does not cache values of an unbound column, because it is impossible to determine when the cache should be cleared automatically. GridView just displays values provided by the CustomUnboundColumnData (see CustomUnboundColumnData) event. So, to display a specific value in a cell, you need to pass a corresponding value to the e.Value parameter based on a processed column and row. What you return as the e.Value parameter is what is displayed in GridView. Each time a cell needs to be updated, the CustomUnboundColumnData (see CustomUnboundColumnData) event is called.
This example demonstrates how a simple caching mechanism can be implemented. In this project, you can perform all supported operations with GridView, such as sorting/deleting/adding records, and the unbound column will display proper values. This is because values of the ID column are used as key values. This column is read-only and contains only unique values. So, rows can be always identified.
You can also use the GridColumn.UnboundExpression property to specify and unbound expression. Please refer to the Unbound Columns help article for additional information.
MyCache.cs |
using System;
using System.Collections.Generic;
using System.Data;
namespace WindowsApplication1
{
public class MyCache
{
private readonly string _KeyFieldName;
Dictionary<object, object> valuesCache = new Dictionary<object, object>();
public MyCache(string keyFieldName)
{
_KeyFieldName = keyFieldName;
}
public object GetKeyByRow(object row)
{
return (row as DataRowView)[_KeyFieldName];
}
public object GetValue(object row)
{
return GetValueByKey(GetKeyByRow(row));
}
public object GetValueByKey(object key)
{
object result = null;
valuesCache.TryGetValue(key, out result);
return result;
}
public void SetValue(object row, object value)
{
SetValueByKey(GetKeyByRow(row), value);
}
public void SetValueByKey(object key, object value)
{
valuesCache[key] = value;
}
}
}
|
Form1.cs |
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using DevExpress.XtraGrid.Columns;
namespace WindowsApplication1
{
public partial class Form1 : Form
{
private DataColumn _KeyField;
private DataTable _Tbl;
private MyCache _Cache = new MyCache("ID");
private DataTable CreateTable(int RowCount)
{
_Tbl = new DataTable();
_KeyField = _Tbl.Columns.Add("ID", typeof(int));
_KeyField.ReadOnly = true;
_KeyField.AutoIncrement = true;
_Tbl.Columns.Add("Name", typeof(string));
_Tbl.Columns.Add("Number", typeof(int));
_Tbl.Columns.Add("Date", typeof(DateTime));
for (int i = 0; i < RowCount; i++)
_Tbl.Rows.Add(new object[] { null, String.Format("Name{0}", i), 3 - i, DateTime.Now.AddDays(i) });
return _Tbl;
}
public Form1()
{
InitializeComponent();
gridControl1.DataSource = CreateTable(20);
CreateUnboundColumn();
}
private void CreateUnboundColumn()
{
GridColumn col = gridView1.Columns.AddVisible("Unbound", "Unbound column");
col.UnboundType = DevExpress.Data.UnboundColumnType.String;
}
private void gridView1_CustomUnboundColumnData(object sender, DevExpress.XtraGrid.Views.Base.CustomColumnDataEventArgs e)
{
if (e.IsGetData)
e.Value = _Cache.GetValue(e.Row);
if (e.IsSetData)
_Cache.SetValue(e.Row, e.Value);
}
}
}
|
Form1.vb |
Imports Microsoft.VisualBasic
Imports System
Imports System.Collections.Generic
Imports System.ComponentModel
Imports System.Data
Imports System.Drawing
Imports System.Text
Imports System.Windows.Forms
Imports DevExpress.XtraGrid.Columns
Namespace WindowsApplication1
Partial Public Class Form1
Inherits Form
Private _KeyField As DataColumn
Private _Tbl As DataTable
Private _Cache As New MyCache("ID")
Private Function CreateTable(ByVal RowCount As Integer) As DataTable
_Tbl = New DataTable()
_KeyField = _Tbl.Columns.Add("ID", GetType(Integer))
_KeyField.ReadOnly = True
_KeyField.AutoIncrement = True
_Tbl.Columns.Add("Name", GetType(String))
_Tbl.Columns.Add("Number", GetType(Integer))
_Tbl.Columns.Add("Date", GetType(DateTime))
For i As Integer = 0 To RowCount - 1
_Tbl.Rows.Add(New Object() { Nothing, String.Format("Name{0}", i), 3 - i, DateTime.Now.AddDays(i) })
Next i
Return _Tbl
End Function
Public Sub New()
InitializeComponent()
gridControl1.DataSource = CreateTable(20)
CreateUnboundColumn()
End Sub
Private Sub CreateUnboundColumn()
Dim col As GridColumn = gridView1.Columns.AddVisible("Unbound", "Unbound column")
col.UnboundType = DevExpress.Data.UnboundColumnType.String
End Sub
Private Sub gridView1_CustomUnboundColumnData(ByVal sender As Object, ByVal e As DevExpress.XtraGrid.Views.Base.CustomColumnDataEventArgs) Handles gridView1.CustomUnboundColumnData
If e.IsGetData Then
e.Value = _Cache.GetValue(e.Row)
End If
If e.IsSetData Then
_Cache.SetValue(e.Row, e.Value)
End If
End Sub
End Class
End Namespace
|
MyCache.vb |
Imports Microsoft.VisualBasic
Imports System
Imports System.Collections.Generic
Imports System.Data
Namespace WindowsApplication1
Public Class MyCache
Private ReadOnly _KeyFieldName As String
Private valuesCache As New Dictionary(Of Object, Object)()
Public Sub New(ByVal keyFieldName As String)
_KeyFieldName = keyFieldName
End Sub
Public Function GetKeyByRow(ByVal row As Object) As Object
Return (TryCast(row, DataRowView))(_KeyFieldName)
End Function
Public Function GetValue(ByVal row As Object) As Object
Return GetValueByKey(GetKeyByRow(row))
End Function
Public Function GetValueByKey(ByVal key As Object) As Object
Dim result As Object = Nothing
valuesCache.TryGetValue(key, result)
Return result
End Function
Public Sub SetValue(ByVal row As Object, ByVal value As Object)
SetValueByKey(GetKeyByRow(row), value)
End Sub
Public Sub SetValueByKey(ByVal key As Object, ByVal value As Object)
valuesCache(key) = value
End Sub
End Class
End Namespace
|