Cells¶
Cells in a Grid control are used to display and edit row values. They are formed at the intersections of rows and columns. While cells present the data, their behavior and appearance (for example, in-place editors and formatting settings) are usually defined by the properties of their parent columns. This topic summarizes how to manage and obtain cell content and to customize cell appearance.
Format Cell Values¶
The Data Grid control allows you present cell values using common and custom formats. For instance, you can format numeric values as a currency, a percentage, an integer or float number, and so on. A DateTime value can be presented in a short date format, long date format, only time format, etc.
The following approaches are available to format cell values:
Use Masked Input¶
Eremex editors allow you to use masks to restrict data input and format numeric and date-time values. Masks are supported both for standalone editors and editors embedded in container controls (DataGrid, TreeList, PropertyGrid, and so on).
Applicable to: Cells in display and edit mode. To prevent masks from being applied in display mode (when cell editing is not active), disable the editor's MaskUseAsDisplayFormat property.
Steps:
- Assign an Eremex in-place editor to a column.
- Set the editor's
MaskTypeproperty toMaskType.NumericorMaskType.DateTimeto apply a mask to numeric or date-time values, respectively. -
Set the editor's
Maskproperty to the required mask. See the following topics for information on mask specifiers:
Example - Custom Format Date-time Values Using Masks¶
The following example assigns a DateEditor to a column, and applies a custom date-time mask ("MMMM dd, yyyy"). This mask formats cell values in edit and display mode, as shown in the image below:

<mxdg:GridColumn FieldName="BirthDate" Width="*" MinWidth="80">
<mxdg:GridColumn.EditorProperties>
<mxe:DateEditorProperties MaskType="DateTime" Mask="MMMM dd, yyyy"/>
</mxdg:GridColumn.EditorProperties>
</mxdg:GridColumn>
Set a Display Format¶
You can use standard and custom format specifiers to format cell values in display mode.
Applicable to: Cells in display mode.
Drawbacks: Display formats are not applied in edit mode, nor do they restrict user input. For example, users still able to enter letters in numeric columns that use text editors. To format values in display and edit modes and to restrict data input, use dedicated editors (SpinEditor for numeric values, DateEditor for date-time values) or apply masks to your text editor.
Steps:
- Assign an Eremex in-place editor to a column.
- Set the editor's display format using its
DisplayFormatStringproperty. -
For editors that use masks for display value formatting, disable the editor's
MaskUseAsDisplayFormatproperty. For example, DateEditor and SpinEditor use masks for value formatting in display mode, by default. So, disabling theMaskUseAsDisplayFormatproperty is required for these editors to apply the display format specified by theDisplayFormatStringproperty.You can find the description of all display formats in the .NET documentation:
Example - Format Date-Time Values Differently in Display and Edit Modes¶
The following example assigns a DateEditor in-place editor to a column, and uses its settings to apply different value formatting in display and edit modes:
- The
DisplayFormatStringproperty is set to 'd'. This setting applies the short date format to values in display mode. For theDisplayFormatStringproperty to be in effect, theMaskUseAsDisplayFormatproperty is disabled. - The
Maskproperty is set to 'g'. This format enables the full date-time pattern with long time in edit mode.

<mxdg:GridColumn FieldName="OrderDate" Width="3*" BandName="AdditionalInformation" >
<mxdg:GridColumn.EditorProperties>
<mxe:DateEditorProperties DisplayFormatString="d" Mask="g" MaskUseAsDisplayFormat="False" />
</mxdg:GridColumn.EditorProperties>
</mxdg:GridColumn>
Example - Format Values as Currency¶
The following example assigns a TextEditor in-place editor to a column, and sets the editor's DisplayFormatString property to the "c" string. This format displays cell values as a currency when cells are in display mode:

<mxdg:GridColumn FieldName="Price" Width="2*">
<mxdg:GridColumn.EditorProperties>
<mxe:TextEditorProperties DisplayFormatString="c" />
</mxdg:GridColumn.EditorProperties>
</mxdg:GridColumn>
Example - Custom Format Float Values¶
The code below assigns a TextEditor in-place editor to a column, and sets the DisplayFormatString property to the "{}{0:F1} kW" string. This format displays float values with one digit after the decimal point, and adds the "kW" suffix to the output. When a cell is in edit mode, the display format is not applied. The "{}" string is an escape token that allows the XAML parser to treat a string starting with an open curly brace ("{") as literal text rather than a markup extension.

<mxdg:GridColumn FieldName="PowerConsumption" Width="1.2*" >
<mxdg:GridColumn.EditorProperties>
<mxe:TextEditorProperties DisplayFormatString="{}{0:F1} kW" />
</mxdg:GridColumn.EditorProperties>
</mxdg:GridColumn>
Format Display Values Using an Event¶
Applicable to: Cells in display mode
If no display format or mask meets your requirements, you can handle the CustomColumnDisplayText event to format cell values in a custom manner. This event allows you to replace default text representatation of values in cells and column filters. To supply custom value display text for group rows, handle the DataGridControl.CustomGroupValueDisplayText event.
When you change cell display text, underlying cell values are not modified.
Example - Custom Format Cell Values Using the CustomColumnDisplayText Event¶
The following CustomColumnDisplayText event handler displays the "pcs" string after cell values in the "Stock" column. Custom display values provided using this event are ignored when cells are being edited.

using Eremex.AvaloniaUI.Controls.DataGrid;
private void DataGrid_CustomColumnDisplayText(object sender, DataGridCustomColumnDisplayTextEventArgs e)
{
if (e.Column.FieldName == "Stock")
e.DisplayText = string.Format("{0} pcs", e.Value);
}
Value Alignment¶
Default horizontal content alignment in cells vary by cell data type:
- Numeric values are aligned to the right.
- Boolean values (check boxes) are centered.
- Other values are aligned to the left.
Vertically cell values are centered, by default.
To custom align values in cells horizontally or vertically, do the following:
- Assign an Eremex in-place editor to a column.
- Use the editor's
HorizontalContentAlignmentproperty to set the horizontal alignment. - Use the editor's
VerticalContentAlignmentproperty to set the vertical alignment.
Example - Center Column Values and Header¶
The following code centers values and header in the Hire Date column. To align cell values, the code assigns a DateEditorin-place editor to this column, and then sets the editor's HorizontalContentAlignment property to Center.
To align the column header's content, the column's HorizontalContentAlignment property is used.

<mxdg:GridColumn FieldName="HireDate" Width="*" MinWidth="80" HeaderHorizontalAlignment="Center">
<mxdg:GridColumn.EditorProperties>
<mxe:DateEditorProperties HorizontalContentAlignment="Center"/>
</mxdg:GridColumn.EditorProperties>
</mxdg:GridColumn>
Multi-line Text and Text Wrapping in Cells¶
Do the following to display multi-line text in cells:
- Assign a TextEditor in-place editor (or its descendant) to a column.
- Use the editor's
TextWrappingproperty to enable text wrapping.
When text wrapping is enabled, the heights of rows are automatically adjusted to display cell contents in their entirety.
Example - Enable Text Wrapping in Cells¶
The following code assigns a text editor to a column and enables text wrapping for this editor.

<mxdg:GridColumn FieldName="Notes" Width="*" MinWidth="80">
<mxdg:GridColumn.EditorProperties>
<mxe:TextEditorProperties TextWrapping="Wrap"/>
</mxdg:GridColumn.EditorProperties>
</mxdg:GridColumn>
Provide Data for Cells¶
Cells in the DataGrid control belong to either bound or unbound columns.
Bound columns are linked to fields (properties) in the control's underlyinga data source. The GridColumn.FieldName properties of these columns are set to the field names that exist in the data source.
Cells of bound columns get their values from corresponding data source fields.
Unbound columns (also called calculated columns) allow you to display (and optionally edit) values that are not present in the data source. For instance, you can create a read-only unbound column that displays values calculated from multiple other fields. Values for unbound columns are provided with the CustomUnboundColumnData event. You can also create editable unbound columns. In this case, your CustomUnboundColumnData event handler must also save data entered by users (for instance, you can save it to a cache or a data source).
Unbound columns can be used to customize display text of cells. For information on other methods for display text customization, see Customize Display Text of Cells.
Example — Create a Calculated Column¶
The following example creates an unbound column Year Total. The CustomUnboundColumnData event handler calculates values for this column as a sum of Quarter1, Quarter2, Quarter3 and Quarter4 fields.

<!-- MainWindow.axaml -->
xmlns:mxdg="https://schemas.eremexcontrols.net/avalonia/datagrid"
xmlns:mxe="https://schemas.eremexcontrols.net/avalonia/editors"
xmlns:sys="clr-namespace:System;assembly=System.Runtime"
<mxdg:DataGridControl Name="dataGrid1" Margin="10" BorderThickness="1"
ItemsSource="{Binding Revenues}"
CustomUnboundColumnData="dataGrid1_CustomUnboundColumnData" >
<mxdg:DataGridControl.Columns>
<mxdg:GridColumn FieldName="Description" Width="*" />
<mxdg:GridColumn FieldName="Quarter1" Width="*">
<mxdg:GridColumn.EditorProperties>
<mxe:TextEditorProperties MaskType="Numeric" Mask="c0"/>
</mxdg:GridColumn.EditorProperties>
</mxdg:GridColumn>
<mxdg:GridColumn FieldName="Quarter2" Width="*">
<mxdg:GridColumn.EditorProperties>
<mxe:TextEditorProperties MaskType="Numeric" Mask="c0"/>
</mxdg:GridColumn.EditorProperties>
</mxdg:GridColumn>
<mxdg:GridColumn FieldName="Quarter3" Width="*">
<mxdg:GridColumn.EditorProperties>
<mxe:TextEditorProperties MaskType="Numeric" Mask="c0"/>
</mxdg:GridColumn.EditorProperties>
</mxdg:GridColumn>
<mxdg:GridColumn FieldName="Quarter4" Width="*">
<mxdg:GridColumn.EditorProperties>
<mxe:TextEditorProperties MaskType="Numeric" Mask="c0"/>
</mxdg:GridColumn.EditorProperties>
</mxdg:GridColumn>
<mxdg:GridColumn Name="colYearTotal" FieldName="YearTotal"
Width="*" ReadOnly="True" UnboundDataType="{x:Type sys:Decimal}" >
<mxdg:GridColumn.EditorProperties>
<mxe:TextEditorProperties DisplayFormatString="c0"/>
</mxdg:GridColumn.EditorProperties>
</mxdg:GridColumn>
</mxdg:DataGridControl.Columns>
</mxdg:DataGridControl>
// MainWindow.axaml.cs
private void dataGrid1_CustomUnboundColumnData(object? sender, DataGridUnboundColumnDataEventArgs e)
{
if (e.IsGettingData && e.Column.FieldName == "YearTotal")
{
RevenueViewModel rec = e.Item as RevenueViewModel;
if (rec != null)
{
e.Value = rec.Quarter1 + rec.Quarter2 + rec.Quarter3 + rec.Quarter4;
}
}
}
// MainWindowViewModel.cs
public partial class MainWindowViewModel : ObservableObject
{
[ObservableProperty]
List<RevenueViewModel> revenues;
public MainWindowViewModel()
{
revenues = new List<RevenueViewModel>
{
new() { Description = "2025 Revenue", Quarter1 = 1250000m, Quarter2 = 1425000m, Quarter3 = 1680000m, Quarter4 = 1950000m },
new() { Description = "2026 Revenue", Quarter1 = 1100000m, Quarter2 = 1250000m, Quarter3 = 1450000m, Quarter4 = 1750000m },
new() { Description = "2027 Revenue", Quarter1 = 950000m, Quarter2 = 1050000m, Quarter3 = 1200000m, Quarter4 = 1400000m },
};
}
}
public partial class RevenueViewModel : ObservableObject
{
[ObservableProperty]
private string description;
[ObservableProperty]
private decimal quarter1;
[ObservableProperty]
private decimal quarter2;
[ObservableProperty]
private decimal quarter3;
[ObservableProperty]
private decimal quarter4;
}
See the following topic for more information: Unbound Columns.
Customize Display Text of Cells¶
You can handle the CustomColumnDisplayText event to customize display text of specific cells. This event affects only displayed text, but not cell edit values.
The CustomColumnDisplayText event also allows you to modify text representation of cell values in column filters and filter panel. When the CustomColumnDisplayText event fires for values in the filter panel, the event's SourceItemIndex parameter returns -1. To supply custom value display text for group rows, handle the DataGridControl.CustomGroupValueDisplayText event.
If cell display text is dependent of values of other data source fields/properties, you can retrieve these field values using the DataGridControl's methods (DataGridControl.GetSourceItem and DataGridControl.GetSourceItemValue) and the methods of your data source.
Example - Modify Cell Display Text Using an Event¶
The following example handles the CustomColumnDisplayText event to modify display text of HireDate column values.
The grid in the current example displays a collection of EmployeeInfo objects. The EmployeeInfo.HireDate field specifies a date when a person was hired. The EmployeeInfo.Experience field specifies the total number of the employee's working years. The initial layout is shown below:

The CustomColumnDisplayText event handler provides custom display text for HireDate values. Instead of date-time values, the HireDate column will display the number of working years from the hiring date till today, followed by the total number of working years (a value of the Experience column). The captions of the HireDate and Experience columns are replaced with "Company Work Experience" and "Total Work Experience", respectively.

<!-- MainWindow.axaml -->
xmlns:data="clr-n4amespace:AppEmployees.ViewModels"
xmlns:mxdg="https://schemas.eremexcontrols.net/avalonia/datagrid"
xmlns:mxe="https://schemas.eremexcontrols.net/avalonia/editors"
<mxdg:DataGridControl x:Name="dataGrid" ItemsSource="{Binding Employees}" BorderThickness="1" Margin="10">
<mxdg:GridColumn FieldName="FirstName" Width="*" MinWidth="80"/>
<mxdg:GridColumn FieldName="LastName" Width="*" MinWidth="80"/>
<mxdg:GridColumn FieldName="HireDate" Width="*" MinWidth="170" AllowEditing="False"/>
<mxdg:GridColumn FieldName="Experience" Width="*" MinWidth="170" />
<mxdg:GridColumn FieldName="Position" Width="*" MinWidth="100">
<mxdg:GridColumn.EditorProperties>
<mxe:ComboBoxEditorProperties ItemsSource="{Binding Source={x:Static data:MainWindowViewModel.Positions}}" IsTextEditable="False"/>
</mxdg:GridColumn.EditorProperties>
</mxdg:GridColumn>
</mxdg:DataGridControl>
// MainWindow.axaml.cs
public partial class MainWindow : MxWindow
{
public MainWindow()
{
InitializeComponent();
GridColumn colHireDate = dataGrid.Columns["HireDate"];
GridColumn colExperience = dataGrid.Columns["Experience"];
colExperience.Header = "Total Work Experience";
colHireDate.Header = "Company Work Experience";
colHireDate.ColumnFilterMode = Eremex.AvaloniaUI.Controls.DataControl.ColumnFilterMode.DisplayText;
colHireDate.SortMode = Eremex.AvaloniaUI.Controls.DataControl.SortMode.DisplayText;
dataGrid.CustomColumnDisplayText += DataGrid_CustomColumnDisplayText;
}
private void DataGrid_CustomColumnDisplayText(object sender, Eremex.AvaloniaUI.Controls.DataGrid.DataGridCustomColumnDisplayTextEventArgs e)
{
if (e.Column.FieldName != "HireDate")
return;
// Get the currently processed value of the HireDate column.
DateTime hireDate = (DateTime)e.Value;
// Calculate the number of days from the hire date till today.
int workingDays = (int)(DateTime.Now - hireDate).TotalDays;
// Calculate the number of years from the hire date till today.
int workingYears = (int)workingDays / 365;
// Supply custom display text for HireDate values shown in the filter panel.
if (e.SourceItemIndex < 0)
{
e.DisplayText = String.Format($"{workingYears} years");
return;
}
// Get the value of the Experience field.
int totalWorkExperience = (int)dataGrid.GetSourceItemValue(e.SourceItemIndex, "Experience");
// Supply custom display text for HireDate values.
e.DisplayText = String.Format($"{workingYears} years ({totalWorkExperience} total)");
}
}
using CommunityToolkit.Mvvm.ComponentModel;
public partial class MainWindowViewModel : ObservableObject
{
[ObservableProperty]
IList<EmployeeInfo> employees;
public MainWindowViewModel() {
Employees = GenerateEmployeeInfo();
}
//...
}
public partial class EmployeeInfo : ObservableObject
{
[ObservableProperty]
public string firstName;
[ObservableProperty]
public string lastName;
[ObservableProperty]
public DateTime hireDate;
[ObservableProperty]
public int experience;
[ObservableProperty]
public string position;
[ObservableProperty]
}
Get and Set Row Values in Code¶
The DataGrid provides methods to get and set values in individual cells, as well as to work with underlying data objects.
Work with Cell Values¶
The following methods operate on cells addressed by row and column (or field name). These methods use row indexes to identify rows. Row indexes reflect the order of rows in the control, identifying both visible and hidden (within collapsed groups) rows. For more details on row identification, see: Identify and Get Rows.
| Method | Description |
|---|---|
GetCellValue |
Returns the edit (raw) value stored in a specific cell. |
SetCellValue |
Sets a new value in a specific cell. |
GetCellDisplayText |
Returns the formatted display text of a cell, which may differ from the edit value due to column formatting or a custom CustomColumnDisplayText event handler. |
Examples:
// Get the 'Price' field value from the first visible row
decimal price = (decimal)dataGrid.GetCellValue(0, "Price");
// Set a new value for the 'Status' column in the focused row
dataGrid.SetCellValue(dataGrid.FocusedRowIndex, "Status", "Approved");
// Get the formatted display text (e.g., "$100.00" instead of 100)
string displayPrice = dataGrid.GetCellDisplayText(0, "Price");
Work with Underlying Data Objects¶
The DataGrid control includes methods that allow you to retrieve a row's source object (business object) and modify its properties. Use the following members to obtain source items:
| Member | Description |
|---|---|
DataControlBase.FocusedItem |
Gets the source object for the currently focused row. |
GetSourceItem |
Returns the source object by its index in the data source. |
GetSourceItemValue |
Returns the value of a specific field in the data source at the specified index. |
GetSourceItemByRowIndex |
Returns the source object by a row's index. |
GetSourceItemByVisibleRowIndex |
Returns the source object by a row's visible index. |
For an explanation of different row index types, refer to Identify and Get Rows.
Examples¶
// Example 1: Update the focused item's property
EmployeeInfo emp = dataGrid.FocusedItem as EmployeeInfo;
if (emp != null)
{
emp.HiredDate = DateTime.Today;
}
// Example 2: Retrieve and modify an item by a row's visible index
var item = dataGrid.GetSourceItemByVisibleRowIndex(2) as Product;
if (item != null)
{
item.UnitsInStock--;
}
Cell In-place Editors¶
Cell in-place editors serve two purposes:
- Control value display when editing is inactive, including formatting settings and value alignment.
- Provide means to modify values in edit mode.

The DataGrid uses EMX editors to present and edit values of common data types, by default. For instance, double values are presented using the SpinEditor in-place editor, Boolean values are presented using the CheckEditor control, etc.
You can explicitly assign editors to columns/cells using these approaches:
- Specify EMX editors using the
GridColumn.EditorPropertiesproperty. - Specify EMX editors using the
GridColumn.CellTemplateproperty. - Specify custom editors using the
GridColumn.CellTemplateproperty.
The first approach (GridColumn.EditorProperties) s preferred, as it provides the following advantages:
- In-place EMX editors and the DataGrid share the same paint theme, ensuring synchronized appearance settings.
- The DataGrid can correctly obtain display text from cells and export it to various formats (XLSX, PDF, images, and so on). When you use cell templates, cells are exported blank.
- High performance during initialization, display, and scrolling. The control mimics the editor's appearance in display mode; the actual editor is created only when editing begins and destroyed once editing ends.
To specify an in-place EMX editor using the GridColumn.EditorProperties property, do the following:
-
Set the
GridColumn.EditorPropertiesproperty to one of the followingBaseEditorPropertiesclass descendants that corresponds to the required editor type:ButtonEditorProperties— Corresponds to and contains settings specific to theButtonEditorcontrol.CheckEditorProperties— Corresponds to and contains settings specific to theCheckEditorcontrol.ComboBoxEditorProperties— Corresponds to and contains settings specific to theComboBoxEditorcontrol.DateEditorProperties— Corresponds to and contains settings specific to theDateEditorcontrol.HyperlinkEditorProperties— Corresponds to and contains settings specific to theHyperlinkEditorcontrol.MemoEditorProperties— Corresponds to and contains settings specific to theMemoEditorcontrol.PopupColorEditorProperties— Corresponds to and contains settings specific to thePopupColorEditorcontrol.SegmentedEditorProperties— Corresponds to and contains settings specific to theSegmentedEditorcontrol.SpinEditorProperties— Corresponds to and contains settings specific to theSpinEditorcontrol.TextEditorProperties— Corresponds to and contains settings specific to theTextEditorcontrol.
-
Modify the settings of the specified
BaseEditorPropertiesdescendant object.
Example - Assign a ComboBoxEditor Control to a Column¶
The following example assigns a ComboBoxEditor editor to a column by setting the GridColumn.EditorProperties property to a ComboBoxEditorProperties object. The ComboBoxEditorProperties.ItemsSource property specifies the source of items to display in the combobox editor's dropdown.

<mxdg:GridColumn FieldName="Position" Width="*" MinWidth="150">
<mxdg:GridColumn.EditorProperties>
<mxe:ComboBoxEditorProperties ItemsSource="{Binding Source={x:Static data:EmployeesData.Positions}}" IsTextEditable="False"/>
</mxdg:GridColumn.EditorProperties>
</mxdg:GridColumn>
See the following topic for more information: Data Editing.