Unbound Column in Windows Forms DataGrid (SfDataGrid)
11 Jun 202110 minutes to read
SfDataGrid allows to add additional columns which are not bound with data object from underlying data source. The unbound column can add to SfDataGrid by using GridUnboundColumn class. Unbound columns supports for sorting, filtering, grouping and exporting as normal columns.
this.sfDataGrid.Columns.Add(new GridUnboundColumn() { HeaderText = "Total Price", MappingName = "TotalPrice", Expression = "UnitPrice*Quantity" });
Me.sfDataGrid.Columns.Add(New GridUnboundColumn() With {.HeaderText = "Total Price", .MappingName = "TotalPrice", .Expression = "UnitPrice*Quantity"})
NOTE
It is mandatory to specify the
GridColumn.MappingName
forGridUnboundColumn
with some name to identify the column. It is not necessary to define name of field in the data object.
Populating Data for Unbound Column
The data for unbound column can populate by setting Expression or Format property or through QueryUnboundColumnInfo event.
Using Expression
The arithmetic or logic expression can specify using Expression
property to compute the display value. By default GridUnboundColumn
evaluates the expression with casing. The casing can disable while evaluate the expression by setting CaseSensitive property to false.
Below are the list of Arithmetic and logical operations supported,
Arithmetic operations |
Operator |
Add | + |
Subtract | - |
Multiply | * |
Divide | / |
Power | ^ |
Mod | % |
Greater Than | > |
Less Than | < |
Equal | = |
GreaterThanOrEqual | >= |
LessThanOrEqual | <= |
Add | + |
Logical operations |
Operators |
AND | (char)135 |
OR | (char)136 |
NOT | (char)137 |
GridUnboundColumn unboundColumn = new GridUnboundColumn();
unboundColumn.MappingName = "UnboundColumn";
unboundColumn.HeaderText = "Unbound Column";
unboundColumn.Expression = "UnitPrice * Quantity < 5000" + (char)135 + "UnitPrice < 100";
this.sfDataGrid.Columns.Add(unboundColumn);
Dim unboundColumn As New GridUnboundColumn()
unboundColumn.MappingName = "UnboundColumn"
unboundColumn.HeaderText = "Unbound Column"
unboundColumn.Expression = "UnitPrice * Quantity < 5000" & ChrW(135) & "UnitPrice < 100"
Me.sfDataGrid.Columns.Add(unboundColumn)
Using Format
Format the values of other columns and display the formatted value in unbound column using Format
property.
unboundColumn.Format = "{UnitPrice}% for {OrderID}";
unboundColumn.Format = "{UnitPrice}% for {OrderID}"
Using QueryUnboundColumnInfo Event
The data for unbound column can populated by handling the QueryUnboundColumnInfo event.QueryUnboundColumnInfoArgs of the QueryUnboundColumnInfo
event provides the information about the cell triggered this event.
The QueryUnboundColumnInfoArgs.Value property can get or set based on the UnboundAction
.
UnboundAction - QueryData
denotes the event triggered to query value and cell information.
UnboundAction – CommitData
denotes the event triggered to save the edited value.
this.sfDataGrid.QueryUnboundColumnInfo += sfDataGrid_QueryUnboundColumnInfo;
void sfDataGrid_QueryUnboundColumnInfo(object sender, QueryUnboundColumnInfoArgs e)
{
if (e.UnboundAction == UnboundActions.QueryData)
{
var unitPrice = Convert.ToDouble(e.Record.GetType().GetProperty("UnitPrice").GetValue(e.Record));
var disCount = Convert.ToDouble(e.Record.GetType().GetProperty("Quantity").GetValue(e.Record));
var save = unitPrice * disCount;
e.Value = "$" + save.ToString();
}
}
AddHandler sfDataGrid.QueryUnboundColumnInfo, AddressOf sfDataGrid_QueryUnboundColumnInfo
Private Sub sfDataGrid_QueryUnboundColumnInfo(ByVal sender As Object, ByVal e As QueryUnboundColumnInfoArgs)
If e.UnboundAction = UnboundActions.QueryData Then
Dim unitPrice = Convert.ToDouble(e.Record.GetType().GetProperty("UnitPrice").GetValue(e.Record))
Dim disCount = Convert.ToDouble(e.Record.GetType().GetProperty("Quantity").GetValue(e.Record))
Dim save = unitPrice * disCount
e.Value = "$" & save.ToString()
End If
End Sub
Editing Unbound Column
Cancel the Editing for Unbound Column Cell
The editing of unbound column cell can canceled by handling the SfDataGrid.CurrentCellBeginEdit event.
sfDataGrid.CurrentCellBeginEdit += dataGrid_CurrentCellBeginEdit;
void dataGrid_CurrentCellBeginEdit(object sender, CurrentCellBeginEditEventArgs args)
{
args.Cancel = args.DataColumn.GridColumn is GridUnboundColumn;
}
AddHandler sfDataGrid.CurrentCellBeginEdit, AddressOf dataGrid_CurrentCellBeginEdit
Private Sub dataGrid_CurrentCellBeginEdit(ByVal sender As Object, ByVal args As CurrentCellBeginEditEventArgs)
args.Cancel = TypeOf args.DataColumn.GridColumn Is GridUnboundColumn
End Sub
Saving Edited Value of Unbound Column using QueryUnboundColumnInfo Event
The edited value of unbound column can get from QueryUnboundColumnInfoArgs.Value
property of QueryUnboundColumnInfo
event when UnboundAction is CommitData
.
this.sfDataGrid.QueryUnboundColumnInfo += sfDataGrid_QueryUnboundColumnInfo;
void sfDataGrid_QueryUnboundColumnInfo(object sender, QueryUnboundColumnInfoArgs e)
{
if (e.UnboundAction == UnboundActions.CommitData)
{
var editedValue = e.Value;
}
}
AddHandler sfDataGrid.QueryUnboundColumnInfo, AddressOf sfDataGrid_QueryUnboundColumnInfo
Private Sub sfDataGrid_QueryUnboundColumnInfo(ByVal sender As Object, ByVal e As QueryUnboundColumnInfoArgs)
If e.UnboundAction = UnboundActions.CommitData Then
Dim editedValue = e.Value
End If
End Sub
Read Unbound Column Values
The value of GridUnboundColumn
can get by using GetUnboundCellValue method.
var value = sfDataGrid.GetUnboundCellValue(sfDataGrid.Columns[8], data.OrdersListDetails[10]);
Dim value = sfDataGrid.GetUnboundCellValue(sfDataGrid.Columns(8), data.OrdersListDetails(10))
Appearance
The appearance of the unbound columns cells can be customized by using the CellStyle property.
GridUnboundColumn unboundColumn = new GridUnboundColumn();
unboundColumn.MappingName = "UnboundColumn";
unboundColumn.HeaderText = "Grand Total";
unboundColumn.CellStyle = new CellStyleInfo() { BackColor = Color.DarkCyan, TextColor = Color.White, HorizontalAlignment = HorizontalAlignment.Right };
unboundColumn.Expression = "UnitPrice * Quantity";
this.sfDataGrid.Columns.Add(unboundColumn);
Dim unboundColumn As New GridUnboundColumn()
unboundColumn.MappingName = "UnboundColumn"
unboundColumn.HeaderText = "Grand Total"
unboundColumn.CellStyle = New CellStyleInfo() With {.BackColor = Color.DarkCyan, .TextColor = Color.White, .HorizontalAlignment = HorizontalAlignment.Right}
unboundColumn.Expression = "UnitPrice * Quantity"
Me.sfDataGrid.Columns.Add(unboundColumn)
Customize the Unbound Column Behavior
Overriding Existing CellType
The unbound row cell behavior can customized by overriding existing renderer and replace the default one in SfDataGrid.CellRenderers.
In the below code snippet, GridUnboundCellRenderer is customized to change the text color and replaced the default renderer with customized renderer in SfDataGrid.CellRenderers
collection.
sfDataGrid.CellRenderers.Remove("Unbound");
sfDataGrid.CellRenderers.Add("Unbound", new CustomUnboundCellRenderer());
public class CustomUnboundCellRenderer : GridUnboundCellRenderer
{
protected override void OnEditingComplete(DataColumnBase dataColumn, TextBox currentRendererElement)
{
base.OnEditingComplete(dataColumn, currentRendererElement);
}
protected override void OnInitializeEditElement(DataColumnBase column, RowColumnIndex rowColumnIndex, TextBox uiElement)
{
base.OnInitializeEditElement(column, rowColumnIndex, uiElement);
}
protected override void OnRender(Graphics paint, Rectangle cellRect, string cellValue, CellStyleInfo style, DataColumnBase column, RowColumnIndex rowColumnIndex)
{
style.TextColor = Color.DarkBlue;
base.OnRender(paint, cellRect, cellValue, style, column, rowColumnIndex);
}
}
sfDataGrid.CellRenderers.Remove("Unbound")
sfDataGrid.CellRenderers.Add("Unbound", New CustomUnboundCellRenderer())
public class CustomUnboundCellRenderer : GridUnboundCellRenderer
protected override void OnEditingComplete(DataColumnBase dataColumn, TextBox currentRendererElement)
MyBase.OnEditingComplete(dataColumn, currentRendererElement)
protected override void OnInitializeEditElement(DataColumnBase column, RowColumnIndex rowColumnIndex, TextBox uiElement)
MyBase.OnInitializeEditElement(column, rowColumnIndex, uiElement)
protected override void OnRender(Graphics paint, Rectangle cellRect, String cellValue, CellStyleInfo style, DataColumnBase column, RowColumnIndex rowColumnIndex)
style.TextColor = Color.DarkBlue
MyBase.OnRender(paint, cellRect, cellValue, style, column, rowColumnIndex)