ColumnView.CustomUnboundColumnData Event

Fires for all cells of visible unbound columns. Allows you to manually provide data to these cells, and save values entered by users at runtime.

Namespace: DevExpress.XtraGrid.Views.Base

Assembly: DevExpress.XtraGrid.v20.2.dll


public event CustomColumnDataEventHandler CustomUnboundColumnData
Public Event CustomUnboundColumnData As CustomColumnDataEventHandler

Event Data

The CustomUnboundColumnData event's data class is CustomColumnDataEventArgs. The following 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.


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 ColumnView.GetListSourceRowCellValue method or methods provided by row objects.


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.


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.

using DevExpress.XtraGrid.Views.Base;
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraGrid.Columns;

private void Form1_Load(object sender, System.EventArgs e) {
   // ...

   // Create an unbound column.
   GridColumn unbColumn = gridView1.Columns.AddField("Total");
   unbColumn.VisibleIndex = gridView1.Columns.Count;
   unbColumn.UnboundType = DevExpress.Data.UnboundColumnType.Decimal;
   // Disable editing.
   unbColumn.OptionsColumn.AllowEdit = false;
   // Specify format settings.
   unbColumn.DisplayFormat.FormatType = DevExpress.Utils.FormatType.Numeric;
   unbColumn.DisplayFormat.FormatString = "c";
   // Customize the appearance settings.
   unbColumn.AppearanceCell.BackColor = Color.LemonChiffon;

// Returns the total amount for a specific row.
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);

// Provides data for the Total column.
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);

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 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 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.

View Example

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;
See Also