Back to Devexpress

Unbound Columns

windowsforms-1477-controls-and-libraries-data-grid-unbound-columns.md

latest12.6 KB
Original Source

Unbound Columns

  • May 01, 2025
  • 6 minutes to read

Unbound (‘dynamic’) columns are Grid columns that display any custom data. You can utilize unbound columns to show data from external sources, combine multiple data sources into one, or use expressions to calculate values based on values in other columns.

Unbound and bound columns are objects of the same type: GridColumn, BandedGridColumn, or LayoutViewColumn. Unbound columns fully support all column features — sorting, grouping, filtering, editing, summaries, etc.

YouTube video

Run Demo View Example

Note

The WinForms Data Grid cannot operate without a data source, even if all of your columns are unbound. Utilize the UnboundSource component to inform the Data Grid how many rows it should generate.

Create Unbound Columns

Create Unbound Columns at Design Time

To create an unbound column at design time, do the following:

  1. Run the Grid Designer.
  2. Switch to “Columns”.
  3. Click the “Add Column” button.
  4. Set the following column properties:
  • GridColumn.FieldName — You must set this property to a unique value that does not match any field name in the grid’s data source.
  • GridColumn.UnboundDataType — Set this property to the type of data your column should display. Columns automatically use in-place editors that correspond to the selected data type.
  1. Populate the unbound column with data. Use the GridColumn.UnboundExpression property or handle the ColumnView.CustomUnboundColumnData event. Read the following sections in this topic for additional information: Unbound Expressions and Editable Unbound Columns with Custom Data.

Create Unbound Columns in Code

The following example creates an unbound column in code. You should explicitly set the unbound column’s visibility and add the column to the view’s Columns collection.

csharp
using System;
using System.Data;
using DevExpress.XtraEditors;
using DevExpress.XtraGrid.Columns;

namespace DXApplication9 {
    public partial class Form1 : XtraForm {
        public Form1() {
            InitializeComponent();
            gridControl1.DataSource = InitDataTable();
            Load += Form1_Load;
        }

        private void Form1_Load(object sender, EventArgs e) {
            GridColumn unboundColumn = new GridColumn() {
                Caption = "Total (Unbound Column)",
                FieldName = "Total",
                UnboundDataType = typeof(double),
                UnboundExpression = "[Price]*(1 - [Discount])",
                Visible = true
            };
            gridView1.Columns.Add(unboundColumn);
        }

        DataTable InitDataTable() {
            DataTable table = new DataTable("DataRecords");
            table.Columns.AddRange(new DataColumn[] {
                new DataColumn("Price", typeof(int)),
                new DataColumn("Discount", typeof(double))
            });
            table.Rows.Add(new object[] { 19.99, 0.1 });
            table.Rows.Add(new object[] { 33.99, 0.25});
            table.Rows.Add(new object[] { 89.99, 0.5 });
            return table;
        }
    }
}
vb
Imports System
Imports System.Data
Imports DevExpress.XtraEditors
Imports DevExpress.XtraGrid.Columns

Namespace DXApplication9
    Partial Public Class Form1
        Inherits XtraForm

        Public Sub New()
            InitializeComponent()
            gridControl1.DataSource = InitDataTable()
            AddHandler Load, AddressOf Form1_Load
        End Sub

        Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs)
            Dim unboundColumn As New GridColumn() With {
                .Caption = "Total (Unbound Column)",
                .FieldName = "Total",
                .UnboundDataType = GetType(Double),
                .UnboundExpression = "[Price]*(1 - [Discount])",
                .Visible = True
            }
            gridView1.Columns.Add(unboundColumn)
        End Sub

        Private Function InitDataTable() As DataTable
            Dim table As New DataTable("DataRecords")
            table.Columns.AddRange(New DataColumn() {
                New DataColumn("Price", GetType(Integer)),
                New DataColumn("Discount", GetType(Double))
            })
            table.Rows.Add(New Object() { 19.99, 0.1 })
            table.Rows.Add(New Object() { 33.99, 0.25})
            table.Rows.Add(New Object() { 89.99, 0.5 })
            Return table
        End Function
    End Class
End Namespace

Unbound Expressions

Unbound expressions allow you to calculate values of unbound columns based on values in other columns. Use our Expression Editor to quickly create expressions. To invoke the Expression Editor, click the ellipsis button next to the GridColumn.UnboundExpression property in the Properties window:

Use the GridColumn.UnboundExpression property to specify the unbound expression in code. The expression is specified as a string.

The following example specifies the unbound expression that calculates the year by subtracting values of the “Int” column from the current year:

csharp
unboundColumn1.UnboundExpression = "GetYear(AddYears(LocalDateTimeNow(), - [Int]))";
vb
unboundColumn1.UnboundExpression = "GetYear(AddYears(LocalDateTimeNow(), - [Int]))"

Tip

Unbound columns that utilize expressions remain editable. Since cell values are calculated according to an expression, edits made by users are automatically discarded. It is recommended that you disable the OptionsColumn.AllowEdit setting for such columns (if data editing is not needed).

Read the following section in this topic for information on how to edit values in unbound columns: Editable Unbound Columns with Custom Data.

Run Demo: Unbound Expressions

Modify Unbound Expressions at Runtime

Enable the GridColumn.ShowUnboundExpressionMenu setting to display the “Expression Editor…” item in the column’s popup menu and allow users to modify the unbound expression.

Use the ColumnViewOptionsBehavior.UnboundColumnExpressionEditorMode property to specify whether to use a legacy Editor (the same one you use at design time), or its updated version that supports syntax highlighting and auto-completion.

Run Demo: Unbound Expressions

Editable Unbound Columns with Custom Data

The ColumnView.CustomUnboundColumnData event allows you to do the following:

  • Populate cells in unbound columns with values.
  • Obtain user edits (which you can accept or discard). Read values of the e.IsGetData and e.IsSetData properties to specify a different set of actions for each of these scenarios:

The following example demonstrates how to retrieve data from a Dictionary and save changes back to it:

csharp
// Creates an unbound column that supports editing.
GridColumn unboundColumn = gridView.Columns.AddField("CustomData");
unboundColumn.UnboundDataType = typeof(string);
unboundColumn.Visible = true;
// Handles the CustomUnboundColumnData event.
Dictionary<int, string> unboundData = new Dictionary<int, string>();
unboundData[1] = "Can live up to 20 years!";
gridView.CustomUnboundColumnData += (sender, e) =>
{
    if(e.Column.FieldName == "CustomData") {
        // Populates columns.
        if(e.IsGetData) {
            if(unboundData.ContainsKey(e.ListSourceRowIndex)) 
                e.Value = unboundData[e.ListSourceRowIndex];
        }
        // Posts edits back to the data source.
        if(e.IsSetData && e.Value != null) {
            unboundData[e.ListSourceRowIndex] = e.Value.ToString();
        }
    }
};
vb
' Creates an unbound column that supports editing.
Dim unboundColumn As GridColumn = gridView.Columns.AddField("CustomData")
unboundColumn.UnboundDataType = GetType(String)
unboundColumn.Visible = True
' Handles the CustomUnboundColumnData event.
Dim unboundData As New Dictionary(Of Integer, String)()
unboundData(1) = "Can live up to 20 years!"
AddHandler gridView.CustomUnboundColumnData, Sub(sender, e)
    If e.Column.FieldName = "CustomData" Then
        ' Populates columns.
        If e.IsGetData Then
            If unboundData.ContainsKey(e.ListSourceRowIndex) Then
                e.Value = unboundData(e.ListSourceRowIndex)
            End If
        End If
        ' Posts edits back to the data source.
        If e.IsSetData AndAlso e.Value IsNot Nothing Then
            unboundData(e.ListSourceRowIndex) = e.Value.ToString()
        End If
    End If
End Sub

Run Demo: How to Edit Unbound Columns

Refresh Unbound Columns

Data-aware controls (for example, the Data Grid) do not cache values in unbound columns/rows, and request these values every time a control is painted, filtered, sorted, etc. Use this behavior to trigger an update and reload unbound values. You can do the following:

Cheat Sheets and Best Practices

Read the following quick-reference guide for general information and examples:

Show Values from External Sources. Calculated Field Values. Unbound Mode.

See Also

Tutorial: Unbound Columns

Data Binding

Grid Columns