windowsforms-1477-controls-and-libraries-data-grid-unbound-columns.md
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.
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.
To create an unbound column at design time, do the following:
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.
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;
}
}
}
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 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:
unboundColumn1.UnboundExpression = "GetYear(AddYears(LocalDateTimeNow(), - [Int]))";
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.
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.
The ColumnView.CustomUnboundColumnData event allows you to do the following:
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:
// 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();
}
}
};
' 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
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:
Reload all currently visible values. Call the BaseView.LayoutChanged method to refresh an entire View.
Reload values in a specific row or cell. Call the ColumnView.RefreshRow or GridView.RefreshRowCell method, respectively.
Read the following quick-reference guide for general information and examples:
Show Values from External Sources. Calculated Field Values. Unbound Mode.
See Also