windowsforms-1473-controls-and-libraries-data-grid-formatting-cell-values.md
The WinForms Data Grid control supports multiple techniques to control the appearance of cell values:
Use these techniques to display values differently from underlying data without data source changes.
Tip
WinForms Cheat Sheet - Display Values Different from Real Underlying Values
Use the simplest approach that meets the requirement:
Display FormattingFormat numeric and date-time values in display mode.MasksRestrict user input and optionally control display text.Dynamic Text CustomizationReplace or modify display text dynamically at runtime (event-based customization).Unbound ColumnsReplace values completely or compute display-only values.Display HTML ContentUse HTML text for rich presentation.
Use the standard .NET formatting mechanism for most usage scenarios. This technique formats values without changing data.
|
Level
|
Property
|
Description
| | --- | --- | --- | |
Column
|
|
Formats cell values in display mode.
| |
Cell Editor
(repository item)
|
|
Formats values in display mode and at edit start. Use input masks instead of EditFormat to control user input.
|
Formatting at the repository item level is useful in the following cases:
Shared FormattingCreate and configure a repository item. Assign it to multiple columns or controls. See the following help topic for additional information: Editors and Simple Controls.Per-cell FormattingCreate multiple repository items with different format settings. Assign them to individual cells within the GridView.CustomRowCellEdit or LayoutView.CustomRowCellEdit event handler.
The following code snippet formats currency and date values in display mode.
// Format a numeric column as currency with no decimals.
GridColumn colModelPrice = gridView1.Columns["ModelPrice"];
colModelPrice.DisplayFormat.FormatType = Utils.FormatType.Numeric;
colModelPrice.DisplayFormat.FormatString = "c0";
// Format a date column as a long date string.
GridColumn colSalesDate = gridView1.Columns["SalesDate"];
colSalesDate.DisplayFormat.FormatType = Utils.FormatType.DateTime;
colSalesDate.DisplayFormat.FormatString = "D";
' Format a numeric column as currency with no decimals.
Dim colModelPrice As GridColumn = gridView1.Columns("ModelPrice")
colModelPrice.DisplayFormat.FormatType = Utils.FormatType.Numeric
colModelPrice.DisplayFormat.FormatString = "c0"
' Format a date column as a long date string.
Dim colSalesDate As GridColumn = gridView1.Columns("SalesDate")
colSalesDate.DisplayFormat.FormatType = Utils.FormatType.DateTime
colSalesDate.DisplayFormat.FormatString = "D"
Note
DisplayFormat does not apply in edit mode. Use masks to control runtime formatting.
Composite patterns combine formatted values with static text.
// Unit price with prefix and three decimals
colUnitPrice.DisplayFormat.FormatType = DevExpress.Utils.FormatType.Numeric;
colUnitPrice.DisplayFormat.FormatString = "UP={0:n3}";
// Quantity with fixed-width integer format
colQuantity.DisplayFormat.FormatType = DevExpress.Utils.FormatType.Numeric;
colQuantity.DisplayFormat.FormatString = "{0:d6}";
// Discount in percent format
colDiscount.DisplayFormat.FormatType = DevExpress.Utils.FormatType.Numeric;
colDiscount.DisplayFormat.FormatString = "({0:P0})";
// Calculated Total column
GridColumn columnTotal = new GridColumn();
columnTotal.Caption = "Total";
columnTotal.FieldName = "Total";
columnTotal.OptionsColumn.AllowEdit = false;
columnTotal.UnboundDataType = typeof(decimal);
columnTotal.UnboundExpression = "[UnitPrice]*[Quantity]*(1-[Discount])";
gridView1.Columns.Add(columnTotal);
columnTotal.VisibleIndex = gridView1.VisibleColumns.Count;
// Currency format with prefix
columnTotal.DisplayFormat.FormatType = DevExpress.Utils.FormatType.Numeric;
columnTotal.DisplayFormat.FormatString = "TTL={0:c2}";
' Unit price with prefix and three decimals
colUnitPrice.DisplayFormat.FormatType = DevExpress.Utils.FormatType.Numeric
colUnitPrice.DisplayFormat.FormatString = "UP={0:n3}"
'Quantity with fixed-width integer format
colQuantity.DisplayFormat.FormatType = DevExpress.Utils.FormatType.Numeric
colQuantity.DisplayFormat.FormatString = "{0:d6}"
' Discount in percent format
colDiscount.DisplayFormat.FormatType = DevExpress.Utils.FormatType.Numeric
colDiscount.DisplayFormat.FormatString = "({0:P0})"
' Calculated Total column
Dim columnTotal As New GridColumn()
columnTotal.Caption = "Total"
columnTotal.FieldName = "Total"
columnTotal.OptionsColumn.AllowEdit = False
columnTotal.UnboundDataType = GetType(Decimal)
columnTotal.UnboundExpression = "[UnitPrice]*[Quantity]*(1-[Discount])"
gridView1.Columns.Add(columnTotal)
columnTotal.VisibleIndex = gridView1.VisibleColumns.Count
' Currency format with prefix
columnTotal.DisplayFormat.FormatType = DevExpress.Utils.FormatType.Numeric
columnTotal.DisplayFormat.FormatString = "TTL={0:c2}"
Tip
Use custom formatters to apply complex formatting. See the following help topic for additional information and examples: Formatting Values.
Use masks to restrict user input or display formatting:
Masks are applied in edit mode by default. Enable the repository item’s UseMaskAsDisplayFormat setting to apply the mask in display mode.
Note
UseMaskAsDisplayFormat can reduce performance with large data sets.
The following image illustrates how to configure mask settings at design time:
See the following help topic for additional information: Input Masks.
The following code snippet enforces a phone number format and applies it to display text:
// Create a text editor with a RegEx mask.
RepositoryItemTextEdit textEdit = new RepositoryItemTextEdit();
textEdit.Mask.MaskType = DevExpress.XtraEditors.Mask.MaskType.RegEx;
textEdit.Mask.EditMask = "(\\(\\d\\d\\d\\) )?\\d{1,3}-\\d\\d-\\d\\d";
textEdit.Mask.UseMaskAsDisplayFormat = true;
// Register the editor and assign it to the column.
gridControl1.RepositoryItems.Add(textEdit);
gridView1.Columns["Phone"].ColumnEdit = textEdit;
' Create a text editor with a RegEx mask.
Dim textEdit As New RepositoryItemTextEdit()
textEdit.Mask.MaskType = DevExpress.XtraEditors.Mask.MaskType.RegEx
textEdit.Mask.EditMask = "(\(\d\d\d\) )?\d{1,3}-\d\d-\d\d"
textEdit.Mask.UseMaskAsDisplayFormat = True
' Register the editor and assign it to the column.
GridControl1.RepositoryItems.Add(textEdit)
GridView1.Columns("Phone").ColumnEdit = textEdit
Handle the ColumnView.CustomColumnDisplayText event to display custom text within specific cells. This technique works when formatting depends on other cell values.
The following code snippet handles the CustomColumnDisplayText event to format prices based on a currency type column.
The currency type column contains only 0 and 1 values. If the currency type equals 0 , the price is displayed in US dollars. If the currency type equals 1 , the price is displayed in euros.
using DevExpress.XtraGrid.Views.Base;
using DevExpress.XtraGrid;
using System.Globalization;
// Culture settings for currency formatting
CultureInfo ciUSA = new CultureInfo("en-US");
CultureInfo ciEUR = new CultureInfo("fr-FR", false);
private void gridView1_CustomColumnDisplayText(object sender, CustomColumnDisplayTextEventArgs e) {
ColumnView view = sender as ColumnView;
// Process only valid data rows and the Price column.
if (e.Column.FieldName != "Price" || e.ListSourceRowIndex == GridControl.InvalidRowHandle)
return;
int currencyType = (int)view.GetListSourceRowCellValue(e.ListSourceRowIndex, "CurrencyType");
decimal price = Convert.ToDecimal(e.Value);
// Select format based on currency type.
e.DisplayText = currencyType == 0
? string.Format(ciUSA, "{0:c}", price)
: string.Format(ciEUR, "{0:c}", price);
}
Imports DevExpress.XtraGrid.Views.Base
Imports DevExpress.XtraGrid
Imports System.Globalization
' Culture settings for currency formatting
Private ciUSA As New CultureInfo("en-US")
Private ciEUR As New CultureInfo("fr-FR", False)
Private Sub gridView1_CustomColumnDisplayText(
sender As Object,
e As CustomColumnDisplayTextEventArgs)
Dim view As ColumnView = TryCast(sender, ColumnView)
' Process only valid data rows and the Price column.
If e.Column.FieldName <> "Price" _
OrElse e.ListSourceRowIndex = GridControl.InvalidRowHandle Then
Return
End If
' Read the currency type from the current row.
Dim currencyType As Integer = CInt(
view.GetListSourceRowCellValue(e.ListSourceRowIndex, "CurrencyType"))
' Convert the original value to Decimal.
Dim price As Decimal = Convert.ToDecimal(e.Value)
' Select the display format based on the currency type.
If currencyType = 0 Then
e.DisplayText = String.Format(ciUSA, "{0:c}", price)
Else
e.DisplayText = String.Format(ciEUR, "{0:c}", price)
End If
End Sub
Use an unbound column when display logic replaces source values completely (when lookup editors do not fit).
Typical use cases include:
The following code snippet handles the CustomUnboundColumnData event to hide zero prices and display empty cells instead.
This example assumes that the Grid Control and its columns are created at design time and are already bound to a data source.
public partial class Form1 : DevExpress.XtraEditors.XtraForm {
public Form1() {
InitializeComponent();
// Hide the original bound column.
gridView1.Columns["Price"].Visible = false;
// Create an unbound replacement column.
GridColumn customColPrice = new GridColumn();
customColPrice.FieldName = "CustomPrice";
customColPrice.Caption = "Custom Price";
customColPrice.UnboundDataType = typeof(string);
customColPrice.Visible = true;
gridView1.Columns.Add(customColPrice);
// Handle CustomUnboundColumnData
gridView1.CustomUnboundColumnData += GridView1_CustomUnboundColumnData;
}
}
void GridView1_CustomUnboundColumnData(object sender, DCustomColumnDataEventArgs e) {
GridView view = sender as GridView;
if (e.Column != view.Columns["CustomPrice"])
return;
// Read the original value from the hidden bound column.
decimal sourceValue = (decimal)view.GetRowCellValue(
view.GetRowHandle(e.ListSourceRowIndex),
view.Columns["Price"]);
// Replace zero with empty text.
e.Value = sourceValue == 0 ? String.Empty : sourceValue.ToString();
}
Imports DevExpress.XtraEditors
Imports DevExpress.XtraGrid.Columns
Imports DevExpress.XtraGrid.Views.Grid
Imports DevExpress.XtraGrid.Views.Base
Public Partial Class Form1
Inherits XtraForm
Public Sub New()
InitializeComponent()
' Hide the original bound column.
gridView1.Columns("Price").Visible = False
' Create an unbound replacement column.
Dim customColPrice As New GridColumn()
customColPrice.FieldName = "CustomPrice"
customColPrice.Caption = "Custom Price"
customColPrice.UnboundDataType = GetType(String)
customColPrice.Visible = True
gridView1.Columns.Add(customColPrice)
' Handle the CustomUnboundColumnData event.
AddHandler gridView1.CustomUnboundColumnData, AddressOf GridView1_CustomUnboundColumnData
End Sub
End Class
Private Sub GridView1_CustomUnboundColumnData(
sender As Object,
e As CustomColumnDataEventArgs)
Dim view As GridView = TryCast(sender, GridView)
If view Is Nothing Then
Return
End If
' Process only the unbound replacement column.
If e.Column IsNot view.Columns("CustomPrice") Then
Return
End If
' Read the original value from the hidden bound column.
Dim sourceValue As Decimal = CDec(
view.GetRowCellValue(
view.GetRowHandle(e.ListSourceRowIndex),
view.Columns("Price")))
' Replace zero with empty text.
If sourceValue = 0D Then
e.Value = String.Empty
Else
e.Value = sourceValue.ToString()
End If
End Sub
Use a simplified HTML syntax when cell content requires rich formatting. This technique allows you to do the following:
Use RepositoryItemHypertextLabel as an in-place editor.
See Also