Skip to main content

Cell Values, Editors, and Validation

  • 29 minutes to read

Get and Modify Cell Values in Code


Use the following methods only when the Grid and its columns are fully initialized. If you need to call these methods while the form is still loading, call the ForceInitialize() method to force the Grid to finish its initialization.

Processed Cell

Read the Cell Value

Change the Cell Value

A focused cell



A cell of a focused row



Any row cell



A cell value in an underlying data source


The currently edited cell



The ColumnView.CellValueChanging and ColumnView.CellValueChanged events raise when a user changes a cell value.

Example 1 - Get cell values

The code below retrieves the value of a cell that belongs to the “ID” column and the third data row (row handle equals 2).

string cellValue;
cellValue = gridView1.GetRowCellValue(2, "ID").ToString();
Example 2 - Get the focused cell text

This code returns the text displayed inside the currently focused cell.

string cellValue = gridView1.GetFocusedDisplayText();
Example 3 - Change the focused cell value

This example changes the value of the focused cell.

gridView1.SetRowCellValue(gridView1.FocusedRowHandle, gridView1.FocusedColumn, "New Value");
gridView1.SetFocusedValue("New Value");
Example 4 - Post edit values immediately

A grid cell editor waits for a user to move focus to another cell or row before its new value is accepted. The code below forces editors to update their values immediately.

    BaseEdit edit = null;
    private void gridView1_ShownEditor(object sender, EventArgs e)
        GridView view = sender as GridView;
        edit = view.ActiveEditor;
        edit.EditValueChanged += edit_EditValueChanged;       

    void edit_EditValueChanged(object sender, EventArgs e)

    private void gridView1_HiddenEditor(object sender, EventArgs e)
        edit.EditValueChanged -= edit_EditValueChanged;
        edit = null;
Example 5 - Auto-adjust cell values

In the Change column cell values based on another column’s values demo, checkboxes under the “Mark” column are automatically checked if you enter a “Length” of more than 10, and cleared otherwise.

gridView.CellValueChanged += (sender, e) => {
    GridView view = sender as GridView;
    if (e.Column.FieldName == "Length") {
        double doubleVal = (double)e.Value;
        view.SetRowCellValue(e.RowHandle, "Mark", doubleVal > 10);


  • In a Data Grid that is bound to a master-detail source, detail data is stored in Clone Views, not Pattern Views. Use the GridView.GetDetailView method to obtain a Clone View. Use the clone view’s GetCellValue or GetRow methods to obtain its cell values and data rows. Read the following topic for more information: How to Work with Master-Detail Relationships in Code.
  • You cannot obtain or modify cell values until there is a row object that corresponds to a record. If a user uses the New Item Row to add new rows, the Data Grid initializes new row objects for these rows only after the user modifies a cell.

Cell Editors

Difference between Repository Items and Real Editors

A data editor is a UI control. A repository item is an object that contains the settings required for a container control (for example, the Data Grid) to create a cell editor.

All DevExpress Data Editors have corresponding repository items. For instance, a RepositoryItemSpinEdit object is a repository item for SpinEdit. Use the editor’s Properties property to access its repository item.

Repository Items and Data Editors - WinForms Data Grid

Grid cells contain repository items. When a user clicks a cell to edit its value, the Grid uses the repository item’s settings to create a cell editor. After the user has finished editing the cell value and has moved the focus, the Grid destroys the cell’s editor. A cell editor (active editor) exists only when the Grid is in edit mode. This technique improves the performance of the Grid.

Default Cell Editors

Grid columns use data editors to display and edit data. Columns automatically create editors depending on the type of data they display. For example, a column that displays date-time values uses the DateEdit.

Data Grid - Date Edit In-Place Editor

Run Demo: Cell Editors Run Demo: Show Buttons in Cells

Data Type Default Editor and Repository Item
String TextEdit, RepositoryItemTextEdit
Numeric SpinEdit, RepositoryItemSpinEdit
Boolean CheckEdit, RepositoryItemCheckEdit
Date-Time DateEdit, RepositoryItemDateEdit
DateTimeOffset DateTimeOffsetEdit, RepositoryItemDateTimeOffsetEdit
TimeSpan TimeEdit, RepositoryItemTimeEdit
Enumeration ComboBoxEdit, RepositoryItemComboBox
Picture/Image PictureEdit, RepositoryItemPictureEdit

Replace Default Cell Editors at Design Time

Invoke a column’s smart tag menu and use the GridColumn.ColumnEdit property’s dropdown to create a new editor or choose an existing editor.

Data Grid - Column Edit Smart Tag

You can also run the Data Grid Designer and open its In-place Editor Repository page to access all in-place editors. You can add, customize, and remove repository items.

Data Grid - Repository Items Designer

Create Cell Editors and Assign Them to Columns in Code

Create a repository item, add it to the Grid’s RepositoryItems collection, and assign the repository item to the GridColumn.ColumnEdit property.

    // Creates a 'ToggleSwitch' repository item.            
    RepositoryItemToggleSwitch edit = new RepositoryItemToggleSwitch();
    // Adds the repository item to the grid's RepositoryItems collection. 
    // Assigns the repository item to the 'Mark' column.
    gridView.Columns["Mark"].ColumnEdit = edit;
How to display a progress bar in a column with numeric values

The code below illustrates how to utilize a ProgressBarControl as an in-place editor for the integer “Relevance” grid column. Users can tap or hold numpad “+” and “-“ keys to modify these integer values.

using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraEditors.Repository;

// Create a repository item
RepositoryItemProgressBar ieProgress = new RepositoryItemProgressBar();
ieProgress.KeyPress += IeProgress_KeyPress;

// Assign the repository item
colRelevance.ColumnEdit = ieProgress;
// Or
private void GridView1_CustomRowCellEdit(object sender, CustomRowCellEditEventArgs e) {
    if (e.Column == colRelevance) e.RepositoryItem = ieProgress;

// Handle + and - key presses
private void IeProgress_KeyPress(object sender, KeyPressEventArgs e) {
    int i = 0;
    if (gridView1.ActiveEditor == null) return;

    if (e.KeyChar == '+') {
        i = (int)gridView1.ActiveEditor.EditValue;
        if (i < 100)
            gridView1.ActiveEditor.EditValue = i + 1;
    if (e.KeyChar == '-') {
        i = (int)gridView1.ActiveEditor.EditValue;
        if (i > 0)
            gridView1.ActiveEditor.EditValue = i - 1;
How to display buttons in cells

The Cell commands to edit and delete rows demo has a “Commands” column with a ButtonEdit cell editor. The editor has two buttons: Edit invokes the Edit Form, and Delete removes the current row.


    // Create the Commands column editor
    RepositoryItemButtonEdit commandsEdit = new RepositoryItemButtonEdit { AutoHeight = false, Name = "CommandsEdit", TextEditStyle = TextEditStyles.HideTextEditor };
    commandsEdit.Buttons.AddRange(new EditorButton[] {
    new EditorButton(ButtonPredefines.Glyph, "Edit", -1, true, true, false, ImageLocation.MiddleLeft, DemoHelper.GetEditImage()),
    new EditorButton(ButtonPredefines.Glyph, "Delete", -1, true, true, false, ImageLocation.MiddleLeft, DemoHelper.GetDeleteImage())});

    // Create an unbound Commands column
    GridColumn _commandsColumn = gridView.Columns.AddField("Commands");
    _commandsColumn.UnboundDataType = typeof(object);
    _commandsColumn.Visible = true;
    _commandsColumn.Width = 100;

    // Hide commandsColumn from EditForm
    _commandsColumn.OptionsEditForm.Visible = DevExpress.Utils.DefaultBoolean.False;

    // Display commands only for the focused row
    gridView.CustomRowCellEdit += (s, e) => {
        if (e.RowHandle == gridView.FocusedRowHandle && e.Column == _commandsColumn)
            e.RepositoryItem = commandsEdit;
    gridView.CustomRowCellEditForEditing += (s, e) => {
        if (e.RowHandle == gridView.FocusedRowHandle && e.Column == _commandsColumn)
            e.RepositoryItem = commandsEdit;

    // Allow only commandsColumn to be edited
    gridView.ShowingEditor += (s, e) => {
        e.Cancel = gridView.FocusedColumn != _commandsColumn;

    gridView.OptionsEditForm.ShowOnDoubleClick = DevExpress.Utils.DefaultBoolean.False;
    gridView.OptionsEditForm.ShowOnEnterKey = DevExpress.Utils.DefaultBoolean.False;
    gridView.OptionsEditForm.ShowOnF2Key = DevExpress.Utils.DefaultBoolean.False;
    gridView.OptionsBehavior.EditingMode = GridEditingMode.EditFormInplace;

    // Perform a specific action when an EditorButton is clicked
    commandsEdit.ButtonClick += (s, e) => {
        switch (e.Button.Caption) {
            case "Edit":
                // Start editing a row using EditForm
            case "Delete":
                // Delete focused row
How to use different editors for cells of the same column

In the Assign in-place editors dynamically demo, the “Length” column receives either a SpinEdit or a CalcEdit editor depending on whether the checkbox under the “Mark” column is checked.

RepositoryItemSpinEdit spinEdit = new RepositoryItemSpinEdit();
RepositoryItemCalcEdit calcEdit = new RepositoryItemCalcEdit();
gridView.Columns["Length"].ShowButtonMode = ShowButtonModeEnum.ShowAlways;

// Handle this event to assign editors to individual cells
gridView.CustomRowCellEdit += (sender, e) => {
    GridView view = sender as GridView;
    if (e.Column.FieldName == "Length") {
        bool boolVal = (bool)view.GetRowCellValue(e.RowHandle, "Mark");
        if (boolVal)
            e.RepositoryItem = spinEdit;
            e.RepositoryItem = calcEdit;

Assign Different Editors to Cells in a Column

Handle the GridView.CustomRowCellEdit event to specify a specific in-place editor for a certain cell or a group of cells.

using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraEditors.Repository;

public Form1() {
    // Creates the repository items.
    RepositoryItem spinEdit = new RepositoryItemSpinEdit();
    RepositoryItem calcEdit = new RepositoryItemCalcEdit();
    // Adds the repository items to the grid's RepositoryItems collection.
    gridControl1.RepositoryItems.AddRange(new RepositoryItem[] { spinEdit, calcEdit });
    /* Handles the 'CustomRowCellEdit' event to assign different editors to cells
    * in the 'Length' column.
    gridView1.CustomRowCellEdit += (sender, e) => {
        GridView view = sender as GridView;
        if(e.Column.FieldName == "Length")
            e.RepositoryItem = (bool)view.GetRowCellValue(e.RowHandle, "Mark") ? spinEdit : calcEdit;

Run Demo: Cell Editors Run Demo: Disable Buttons in Certain Rows

Display Any UI Control in Grid Cells

Use RepositoryItemAnyControl to embed a UI control into a grid cell. The control must implement the DevExpress.XtraEditors.CustomEditor.IAnyControlEdit interface. The DevExpress Gauge Control and Chart Control implement this interface out of the box. You need to implement this interface manually to embed other UI controls in grid cells.

The image below shows the grid cell with an embedded DevExpress Chart control.

Data Grid - In-Place Chart Control

Run Demo: Embedded Gantt Run Demo: Embedded Chart

Use Different Editors to Display and Edit Cell Values

A column uses the same editor to display and edit its values. Handle the CustomRowCellEditForEditing event to use different editors to display and edit column values.

The following example demonstrates how to use ProgressBarControl to display numeric values in the Quantity column, and SpinEdit to edit cell values.

using DevExpress.XtraEditors.Repository;

public Form1() {
    // Creates two repository items.
    RepositoryItem editorForDisplay, editorForEditing;
    // Initializes the repository items.
    editorForDisplay = new RepositoryItemProgressBar();
    editorForEditing = new RepositoryItemSpinEdit();
    // Forces the grid to initialize its settings.
    // Adds the repository items to the grid's RepositoryItems collection.
        new RepositoryItem[] { editorForDisplay, editorForEditing });
    // Assign the 'Progress Bar' repository item to the numeric 'Quantity' column.
    gridView1.Columns["Quantity"].ColumnEdit = editorForDisplay;
    /* Handles the 'CustomRowCellEditForEditing' event to create a Spin Editor
        * when a user edits a cell value in the 'Quantity' column.
    gridView1.CustomRowCellEditForEditing += (sender, e) => {
        if(e.Column.FieldName == "Quantity")
            e.RepositoryItem = editorForEditing;

Run Demo: Use Different In-place Editors for Certain Cells

API to Manage Cell Editors




Invokes the focused cell’s editor.


Closes the active editor and discards the changes made.


Saves any changes made and closes the active editor.


Saves any changes made without closing the active editor.


Gets the active editor.


Fires when the grid activates an in-place editor.

The following example shows how to specify the current date and open the DateEdit‘s dropdown when the user starts to edit a value in the OrderDate column.

using DevExpress.XtraEditors;
using DevExpress.XtraGrid.Views.Grid;

private void GridView1_ShownEditor(object sender, EventArgs e) {
    GridView view = sender as GridView;
    if (view.FocusedColumn == colOrderDate) {
        // Specifies the current date.
        view.EditingValue = DateTime.Today;
        // Gets the active editor.
        DateEdit editor = view.ActiveEditor as DateEdit;
        // Invokes the dropdown.


Fires when an in-place editor closes.

The following example demonstrates how to move cell focus to the next cell in a column after the active editor has been closed. A user does not need to move focus from one cell to another to edit cell values in a column.

using DevExpress.XtraEditors;
using DevExpress.XtraGrid.Views.Grid;

private void GridView1_HiddenEditor(object sender, EventArgs e) {
    GridView view = sender as GridView;
    if (view.FocusedRowHandle == GridControl.NewItemRowHandle) return;
    if (view.FocusedRowHandle == view.RowCount - 1)
        view.FocusedRowHandle = 0;

Edit Data in a Separate Form

Edit Form Modes

Users can use an Edit Form instead of in-place editors to edit data rows. Double-click a grid row or press the Enter or F2 key to invoke the Edit Form. Use the EditingMode property to specify the edit mode.

Data Grid - Inline Edit Form

Grid-based Views support the following Edit Form display modes:

  • Floating Modal Form (default)
  • Inline Edit Form with Data Row (the grid displays the Edit Form below the edited data row)
  • Inline Edit Form (the grid does not display the edited row)

Run Demo: Inline Edit Form Run Demo: Access Editor in Edit Form


Detail Views in Master-Detail Mode do not support in-line edit forms.

Edit Form API




Allows you to turn on the Edit Form and specify its display mode.


Allow you to display and hide the Edit Form.


Specifies whether to show confirmation dialogs when users modify records.


Specifies whether to display the Update and Cancel buttons. Ctrl+Enter saves the changes. Esc discards the changes.


Specifies whether to pass changes to the Grid immediately after a user moves focus to another field in the Edit Form, or after all changes have been accepted.


Specifies the caption of a Floating Edit Form.


Fires before the Edit Form is displayed. Handle this event to hide the Edit Form and prevent a user from editing values in certain cells.

The following example prevents a user from editing cell values in even rows:

gridView.OptionsBehavior.EditingMode = GridEditingMode.EditForm;

gridView1.EditFormShowing += (s, e) => {
    e.Allow = e.RowHandle % 2 != 0; 

Run Demo


The Edit Form uses the Tag property of repository items internally. Do not set the Tag property to avoid runtime issues.

Change Values in Edit Form Fields — Implement Custom Edit Logic

The Edit Form is a container control with data editors (fields). Data editors are bound to corresponding fields/properties in a data record. Do one of the following to specify values of these data editors:

The following example handles the EditFormPrepared event to focus the ‘first’ Date Editor when a user opens the Edit Form.

using DevExpress.XtraGrid.Views.Grid;

// ...
gridView.OptionsBehavior.EditingMode = GridEditingMode.EditForm;

DateEdit dateEdit = null;
gridView.EditFormPrepared += (s, e) => {
    // The 'e.BindableControls' collection contains the editors in the Edit Form.
    foreach (Control item in e.BindableControls) {
        dateEdit = item as DateEdit;
        if (dateEdit != null) {
            // Focuses the Date Editor.

Run Demo: How to Access Editor in Edit Form


Handle the EditFormHidden event to remove the references to Edit Form editors and unsubscribe from event handlers.


This guideline is applicable to other DevExpress Data-Aware Controls that support Edit Forms: Gantt Control, Tree List, etc.

Change Edit Form Layout

The Grid control creates the Edit Form according to the following rules:

  • An Edit Form displays an editor for every visible editable column.
  • If a column uses different editors to edit and display cell values, an Edit Form displays the editors used in Edit mode.
  • An Edit Form’s client area has a table layout with three columns. Each editor (except for MemoEdit and PictureEdit ) occupies a single cell in the table.
  • MemoEdit editors span across all layout columns horizontally and three layout rows vertically.
  • PictureEdit editors span across two layout columns horizontally and three layout rows vertically.


Invoke the Data Grid Designer and switch to the EditForm Designer page to customize the layout of the Edit Form.

Data Grid - Edit Form Designer

Edit Form API




Use this property to customize a column’s editor displayed in the Edit Form.


Disable this option to set custom column and row spans for a column’s editor.

OptionsColumnEditForm.ColumnSpan / OptionsColumnEditForm.RowSpan

Specify the number columns and rows across which a column’s editor spans.

OptionsColumnEditForm.Caption / OptionsColumnEditForm.CaptionLocation

Allow you to specify the editor’s caption and its position.

OptionsColumnEditForm.Visible / OptionsColumnEditForm.VisibleIndex

Use these properties to hide the editor or specify its position among other editors.


Enable this option to display the editor on a new line.

Create Custom Edit Form

  1. Create a User Control. Inherit it from the EditFormUserControl class. If you have partial classes for a User Control, they must also inherit the EditFormUserControl class.
  2. Create the Edit Form UI (customize the User Control as needed).
  3. Use the BoundFieldName and BoundPropertyName properties of the parent class to bind the editors to data source fields.
  4. Assign an instance of the Custom Edit Form to the Grid’s GridOptionsEditForm.CustomEditFormLayout property.
  5. Assign separate instances of the Custom Edit Form to each detail View to use the Custom Edit Form in detail views in Master-Detail Mode.
using DevExpress.XtraGrid.Views.Grid;
// Custom Edit Form
public class AdvancedEditForm : EditFormUserControl {
    public AdvancedEditForm() {
        // Binds the 'EditValue' of the 'textEdit3' editor to the Price field.
        this.SetBoundFieldName(textEdit3, "Price");
        this.SetBoundPropertyName(textEdit3, "EditValue");

// Enables the Custom Edit Form.
gridView1.OptionsEditForm.CustomEditFormLayout = new AdvancedEditForm();

// Enables the Custom Edit Form to edit values in detail views in Master-Detail mode.
void gridControl1_ViewRegistered(object sender, DevExpress.XtraGrid.ViewOperationEventArgs e) {
    GridView detailCloneView = e.View as GridView;
    if(detailCloneView.LevelName == "Order_Details")
        detailCloneView.OptionsEditForm.CustomEditFormLayout = new AdvancedEditForm(); 

Run Demo: Custom Edit Form

Manage User Input

Use Predefined and Custom Masks

Input Masks define the way in which data can be entered within an application to help you get intuitive and error-free data input. The following example demonstrates how to specify a 10-digit phone mask.

repositoryItemTextEdit2.Mask.EditMask = "+1 (000) 000-0000";
repositoryItemTextEdit2.Mask.MaskType = DevExpress.XtraEditors.Mask.MaskType.Numeric;
repositoryItemTextEdit1.Mask.UseMaskAsDisplayFormat = true; // Optional
gridView.Columns["Phone"].ColumnEdit = repositoryItemTextEdit2;

Disable Certain Cells

You can prevent users from editing cell values in a grid or column based on a condition.

Global Grid Settings

Run Demo: Disabled Mode

Disable Cells Based on a Condition

  • Use the Disabled Cell Behavior to disable cells in rows that meet a certain condition. Disabled cells are grayed-out and cannot be edited.
  • Handle the ColumnView.ShowingEditor event and set its Cancel parameter to true.

    The following example handles the ShowingEditor event to disable cells in the focused row if the value in the Country column is “Germany”.

    using DevExpress.XtraGrid.Views.Grid;
    private void gridView1_ShowingEditor(object sender, System.ComponentModel.CancelEventArgs e) {
       GridView view = sender as GridView;
       string cellValue = view.GetRowCellValue(view.FocusedRowHandle, colCountry).ToString();
       if (cellValue == "Germany")
           e.Cancel = true;

    The following example prevents users from editing cells in the “ID” column in odd rows:

    gridView.ShownEditor += (s, e) => {
        GridView view = s as GridView;
        view.ActiveEditor.Properties.ReadOnly =
            gridView.FocusedColumn.FieldName == "ID" && gridView.FocusedRowHandle % 2 == 0;

    Run Demo: Read-Only Mode for Certain Cells

Disable Edit Form Fields Based on a Condition

Use one of the following techniques to disable fields in the Edit Form:

  • Handle the GridView.EditFormPrepared event. Use the e.BindableControls property to access the required editor and disable its Editable property.
  • Create a Custom Edit Form and specify the behavior of editors in EditFormUserControl.

Validate Cells

The Data Grid automatically validates a cell’s value when a user presses Enter or moves focus to another cell in the same row. Use the BaseView.PostEditor method to forcibly validate the cell’s value.

The following diagram illustrates how the grid validates cell values:

Data Grid - Validation - Cell Validation

  • BaseView.ValidatingEditor - Handle this event to check whether a new value is correct. Set the e.Valid parameter accordingly. Users cannot move focus away from a cell with an invalid value until it is corrected or until the Esc key is pressed to cancel the change.
  • BaseView.InvalidValueException - A view raises this event if the e.Valid parameter in the ValidatingEditor event handler has been set to false. This event allows you to specify how the Data Grid responds to an invalid value (ExceptionMode).
  • If the e.ExceptionMode parameter is set to NoAction, a cell does not accept an invalid value and the Grid does not display any notifications. You need to manually notify the user of invalid input. For example, use the ColumnView.SetColumnError method to display error icons.
  • Handle the GridView.RowCellStyle event to highlight cells with invalid values.

Run Demo: Data Validation Run Demo: Validate Active Editor

How to compare cell values

The code sample below checks the order shipping date to ensure that it is not earlier than the date this order was placed.

Data Grid - Validation Dates

private void GridView1_ValidatingEditor(object sender, BaseContainerValidateEditorEventArgs e) {
    GridView view = sender as GridView;
    if (view.FocusedColumn == colRequiredDate) {
        DateTime? requiredDate = e.Value as DateTime?;
        DateTime? orderDate = view.GetRowCellValue(view.FocusedRowHandle, colOrderDate) as DateTime?;
        if (requiredDate < orderDate) {
            e.Valid = false;
            e.ErrorText = "Required Date is earlier than the order date";
How to avoid duplicate values

The following code from the Prevent entering duplicate values demo illustrates how to check the “ID” column values and prevent users from entering repeating IDs.

gridView.ValidatingEditor += (s, e) => {
    string fieldName = string.Empty;
    GridView view = s as GridView;
    EditFormValidateEditorEventArgs ea = e as EditFormValidateEditorEventArgs;
    if(ea == null)
        fieldName = view.FocusedColumn.FieldName;
        fieldName = ea.Column.FieldName;
    int rowCellValue;
    int validatingCellValue = Convert.ToInt32(e.Value);
    if(fieldName == "ID")
        // Iterate through all data rows within GridView
        for(int rowHandle = 0; rowHandle < view.DataRowCount; rowHandle++) {
            // Obtain the ID cell value of the processed row
            rowCellValue = Convert.ToInt32(view.GetRowCellValue(rowHandle, fieldName)); 
            if(rowCellValue == validatingCellValue) {
                e.Valid = false;
                e.ErrorText = "ID should be unique (ValidatingEditor)";

gridView.InvalidValueException += (s, e) => {
    e.ExceptionMode = ExceptionMode.DisplayError;

Validate Rows

The Data Grid validates a data row when a user moves focus to another row. This can be useful to identify conflicts between values in different cells in the same data row (for example, a shipping date cannot be earlier than the order date).

Data Grid - Validate Row Demo

The following diagram illustrates how the grid validates data rows:

Data Grid - Validation - Row Diagram

  • ColumnView.ValidateRow / ColumnView.InvalidRowException - Handle these events to validate data rows and respond to invalid values. A user cannot move focus to another row until they correct all errors. The Esc key cancels the changes.

    private void gridView1_ValidateRow(object sender, DevExpress.XtraGrid.Views.Base.ValidateRowEventArgs e) {
        GridView view = sender as GridView;
        float val = Convert.ToSingle(view.GetRowCellValue(e.RowHandle, gridColumn3)) * 
            Convert.ToInt16(view.GetRowCellValue(e.RowHandle, gridColumn4)) *
            (1 - Convert.ToSingle(view.GetRowCellValue(e.RowHandle, gridColumn5))); //Total Sum
        if(val < 0) {
            e.ErrorText = string.Format("{0}\r\n", Properties.Resources.SubTotalGreaterEqual);
            e.Valid = false;


    A data source must implement IEditableObject to be able to revert row values back to the correct values.

  • ColumnView.SetColumnError - The Data Grid displays a warning message that requires a user to correct or discard the invalid value(s). Use the SetColumnError method to suppress the default notification and display a custom error description and icon in cells with invalid values or in the entire row.

  • Use the ColumnView.UpdateCurrentRow method to force the Grid to validate the focused row.

Run Demo: Validate row on loss of focus

Indicate Invalid Values with IDXDataErrorInfo

Use the DXErrorProvider component and implement the IDXDataErrorInfo interface in a business object to automatically indicate invalid values and display text-based feedback (tooltips).

Indicate Invalid Values with IDXDataErrorInfo - WinForms Data Grid Validation

using DevExpress.XtraGrid.Views.Base;
using DevExpress.XtraEditors.DXErrorProvider;

namespace DXApplication {
    public partial class Form1 : DevExpress.XtraEditors.XtraForm {
        DXErrorProvider errorProvider;
        public Form1() {
            // Initializes a data source and binds it to the grid control.
            List<MyRecord> records = MyRecord.InitData();
            gridControl1.DataSource = records;
            // Initializes the DXErrorProvider component that handles errors.
            errorProvider = new DXErrorProvider(this);
            // Binds the error provider to the data source to track errors.
            errorProvider.DataSource = records;

    public class MyRecord : IDXDataErrorInfo {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public void GetPropertyError(string propertyName, ErrorInfo info) {
            if(propertyName == "FirstName" && FirstName == "" ||
                propertyName == "LastName" && LastName == "")
                info.ErrorText = string.Format("The {0} field cannot be empty", propertyName);
        public void GetError(ErrorInfo info) { }
        static public List<MyRecord> InitData() {
            return new List<MyRecord>() {
                new MyRecord(){ FirstName = "Mike", LastName = "Brown" },
                new MyRecord(){ FirstName = "Sandra", LastName = "Smith"},
                new MyRecord(){ FirstName = "Andy", LastName = "Muller" }

Save User Edits

The Data Grid and other DevExpress data-aware controls (Gantt Control, Vertical Grid, TreeList, etc.) do not interact with real data storages. Instead, they use data sources connected to these storages.

Data-aware controls save user edits to data sources. You should post these changes to underlying storages. Handle the ColumnView.RowUpdated event to post modified row values to the data storage. The Grid raises this event when a user moves focus to another row.

void gridView1_RowUpdated(object sender, RowObjectEventArgs e) {
    // Use data source API to save changes.

Handle the ColumnView.CellValueChanged event to save changes each time the user edits a cell.


Ensure that there is no active editor before you save data to a data storage. The BaseView.IsEditing property must return false. Otherwise, call the BaseView.CloseEditor method to close the active editor, and then call the UpdateCurrentRow() method.

void gridView1_CellValueChanged(object sender, CellValueChangedEventArgs e)  {
    ColumnView view = sender as ColumnView;  
    if(view.UpdateCurrentRow()) {  
        // Use data source API to save changes.

Read the following topic for detailed information: How to Post Data to Underlying Data Storage.

Cheat Sheets and Best Practices

See Also