Back to Devexpress

Edit Data. Create Cell Editors. Validate User Input

windowsforms-753-controls-and-libraries-data-grid-data-editing-and-validation-modify-and-validate-cell-values.md

latest72.6 KB
Original Source

Edit Data. Create Cell Editors. Validate User Input

  • Sep 14, 2025
  • 33 minutes to read

Get and Modify Cell Values in Code

Important

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

|

ColumnView.GetFocusedValue
ColumnView.FocusedValue

|

ColumnView.SetFocusedValue

| |

A cell of a focused row

|

ColumnView.GetFocusedRowCellValue
ColumnView.GetFocusedRowCellDisplayText

|

ColumnView.SetFocusedRowCellValue

| |

Any row cell

|

ColumnView.GetRowCellValue
ColumnView.GetRowCellDisplayText

|

ColumnView.SetRowCellValue

| |

A cell value in an underlying data source

|

ColumnView.GetListSourceRowCellValue

| | |

The currently edited cell

|

ColumnView.EditingValue

|

ColumnView.EditingValue

|

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

Example 1 - Get cell values

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

csharp
string cellValue;
cellValue = gridView1.GetRowCellValue(2, "ID").ToString();
vb
Dim CellValue As String 
CellValue = GridView1.GetRowCellValue(2, "ID")

Example 2 - Get the focused cell text

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

csharp
string cellValue = gridView1.GetFocusedDisplayText();
vb
Dim cellValue As String = GridView1.GetFocusedDisplayText()

Example 3 - Change the focused cell value

This example changes the value of the focused cell.

csharp
gridView1.SetRowCellValue(gridView1.FocusedRowHandle, gridView1.FocusedColumn, "New Value");
//or
gridView1.SetFocusedValue("New Value");
vb
gridView1.SetRowCellValue(gridView1.FocusedRowHandle, gridView1.FocusedColumn, "New Value")
'or
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 following code snippet forces editors to update their values immediately.

csharp
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)
    {
        gridView1.PostEditor();
    }

    private void gridView1_HiddenEditor(object sender, EventArgs e)
    {
        edit.EditValueChanged -= edit_EditValueChanged;
        edit = null;
    }
vb
Private edit As BaseEdit = Nothing
    Private Sub gridView1_ShownEditor(ByVal sender As Object, ByVal e As EventArgs)
        Dim view As GridView = TryCast(sender, GridView)
        edit = view.ActiveEditor
        AddHandler edit.EditValueChanged, AddressOf edit_EditValueChanged
    End Sub

    Private Sub edit_EditValueChanged(ByVal sender As Object, ByVal e As EventArgs)
        gridView1.PostEditor()
    End Sub

    Private Sub gridView1_HiddenEditor(ByVal sender As Object, ByVal e As EventArgs)
        RemoveHandler edit.EditValueChanged, AddressOf edit_EditValueChanged
        edit = Nothing
    End Sub

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, or cleared otherwise.

csharp
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);
    }
};
vb
AddHandler gridView.CellValueChanged, Sub(sender, e)
    Dim view As GridView = TryCast(sender, GridView)
    If e.Column.FieldName = "Length" Then
        Dim doubleVal As Double = CDbl(e.Value)
        view.SetRowCellValue(e.RowHandle, "Mark", doubleVal > 10)
    End If
End Sub

Note

  • 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 clone view 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 adds rows with New Item Row, the Data Grid initializes new row objects for these rows only after the user modifies a cell.

Modify Unbound Column Values

Unbound Columns display calculated or custom data. Handle the ColumnView.CustomUnboundColumnData event and use the e.IsSetData parameter to implement editing in an unbound column.

The following example creates an editable unbound column. The “unboundData” dictionary supplies data to the column.

csharp
using DevExpress.XtraGrid.Columns;
using DevExpress.XtraGrid.Views.Base;

Dictionary<int, int> unboundData = new Dictionary<int, int>();
void Form1_Shown(object sender, EventArgs e) {
    // Create an unbound column
    GridColumn UnboundCol = new GridColumn();
    UnboundCol.UnboundDataType = typeof(int);
    UnboundCol.FieldName = "Custom";
    UnboundCol.Visible = true;
    gridView1.Columns.Add(UnboundCol);
}
void gridView1_CustomUnboundColumnData(object sender, CustomColumnDataEventArgs e) {
    if (e.Column.FieldName == "Custom") {
        // Populate the column with values
        if (e.IsGetData)
            e.Value = unboundData.ContainsKey(e.ListSourceRowIndex) ? unboundData[e.ListSourceRowIndex] : 0;
        // Save user input
        if (e.IsSetData && e.Value != null)
            unboundData[e.ListSourceRowIndex] = (int)e.Value;
    }
}
vb
Imports System
Imports DevExpress.XtraGrid.Columns
Imports DevExpress.XtraGrid.Views.Base

Private unboundData As New Dictionary(Of Integer, Integer)()
Private Sub Form1_Shown(ByVal sender As Object, ByVal e As EventArgs)
    ' Create an unbound column
    Dim UnboundCol As New GridColumn()
    UnboundCol.UnboundDataType = GetType(Integer)
    UnboundCol.FieldName = "Custom"
    UnboundCol.Visible = True
    gridView1.Columns.Add(UnboundCol)
End Sub
Private Sub gridView1_CustomUnboundColumnData(ByVal sender As Object, ByVal e As CustomColumnDataEventArgs)
    If e.Column.FieldName = "Custom" Then
        ' Populate the column with values
        If e.IsGetData Then
            e.Value = If(unboundData.ContainsKey(e.ListSourceRowIndex), unboundData(e.ListSourceRowIndex), 0)
        End If
        ' Save user input
        If e.IsSetData AndAlso e.Value IsNot Nothing Then
            unboundData(e.ListSourceRowIndex) = CInt(Math.Truncate(e.Value))
        End If
    End If
End Sub

Run Demo: How to Edit Unbound Columns

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.

Grid cells contain repository items. When a user clicks a cell to edit its value, the Grid uses repository item settings to create a cell editor. After the user has finished editing the cell value and has moved 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 Grid performance.

The following example gets the active editor within Grid View and clears its value:

csharp
if(gridView1.ActiveEditor != null) {
    gridView1.ActiveEditor.EditValue = null;
}
vb
If gridView1.ActiveEditor IsNot Nothing Then
    gridView1.ActiveEditor.EditValue = Nothing
End If

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.

Run Demo: Cell EditorsRun Demo: Show Buttons in Cells

Data TypeDefault Editor and Repository Item
String, Numeric, TimeOnlyTextEdit, RepositoryItemTextEdit
BooleanCheckEdit, RepositoryItemCheckEdit
Date-Time, DateOnlyDateEdit, RepositoryItemDateEdit
DateTimeOffsetDateTimeOffsetEdit, RepositoryItemDateTimeOffsetEdit
TimeSpanTimeSpanEdit, RepositoryItemTimeSpanEdit
EnumerationComboBoxEdit, RepositoryItemComboBox
Picture/ImagePictureEdit, 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.

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.

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.

csharp
// Creates a 'ToggleSwitch' repository item.            
    RepositoryItemToggleSwitch edit = new RepositoryItemToggleSwitch();
    // Adds the repository item to the grid's RepositoryItems collection. 
    gridControl.RepositoryItems.Add(edit);
    // Assigns the repository item to the 'Mark' column.
    gridView.Columns["Mark"].ColumnEdit = edit;
vb
' Creates a 'ToggleSwitch' repository item.           
    Dim edit As New RepositoryItemToggleSwitch()
    ' Adds the repository item to the grid's RepositoryItems collection.
    gridControl.RepositoryItems.Add(edit)
    ' 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 following code snippet uses 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.

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

// Create a repository item
RepositoryItemProgressBar ieProgress = new RepositoryItemProgressBar();
gridControl1.RepositoryItems.Add(ieProgress);
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;
    }
}
vb
Imports DevExpress.XtraGrid.Views.Grid
Imports DevExpress.XtraEditors.Repository

' Create a repository item
Private ieProgress As New RepositoryItemProgressBar()
gridControl1.RepositoryItems.Add(ieProgress)
Private ieProgress.KeyPress += AddressOf IeProgress_KeyPress

' Assign the repository item
colRelevance.ColumnEdit = ieProgress
' Or
private void GridView1_CustomRowCellEdit(Object sender, CustomRowCellEditEventArgs e)
  If e.Column = colRelevance Then
      e.RepositoryItem = ieProgress
  End If

' Handle + and - keys presses
private void IeProgress_KeyPress(Object sender, KeyPressEventArgs e)
  Dim i As Integer = 0
  If gridView1.ActiveEditor Is Nothing Then
      Return
  End If

  If e.KeyChar = "+"c Then
      i = CInt(Math.Truncate(gridView1.ActiveEditor.EditValue))
      If i < 100 Then
          gridView1.ActiveEditor.EditValue = i + 1
      End If
  End If
  If e.KeyChar = "-"c Then
      i = CInt(Math.Truncate(gridView1.ActiveEditor.EditValue))
      If i > 0 Then
          gridView1.ActiveEditor.EditValue = i - 1
      End If
  End If

How to display buttons in cells

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

csharp
// Create the Commands column editor
    RepositoryItemButtonEdit commandsEdit = new RepositoryItemButtonEdit { AutoHeight = false, Name = "CommandsEdit", TextEditStyle = TextEditStyles.HideTextEditor };
    commandsEdit.Buttons.Clear();
    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())});
    grid.RepositoryItems.Add(commandsEdit);

    // 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
                gridView.CloseEditor();
                gridView.ShowEditForm();
                break;
            case "Delete":
                // Delete focused row
                gridView1.DeleteRow(gridView1.FocusedRowHandle);
                break;
        }
    };
vb
' Create the Commands column editor
    Dim commandsEdit As RepositoryItemButtonEdit = New RepositoryItemButtonEdit With {.AutoHeight = False, .Name = "CommandsEdit", .TextEditStyle = TextEditStyles.HideTextEditor}
    commandsEdit.Buttons.Clear()
    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())
    })
    grid.RepositoryItems.Add(commandsEdit)
    ' Create an unbound Commands column
    Dim _commandsColumn As GridColumn = gridView.Columns.AddField("Commands")
    _commandsColumn.UnboundDataType = GetType(Object)
    _commandsColumn.Visible = True
    _commandsColumn.Width = 100

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

    ' Display commands only for focused row
    AddHandler gridView.CustomRowCellEdit, Sub(s, e)
        If e.RowHandle = gridView.FocusedRowHandle AndAlso e.Column Is _commandsColumn Then
            e.RepositoryItem = commandsEdit
        End If
    End Sub
    AddHandler gridView.CustomRowCellEditForEditing, Sub(s, e)
        If e.RowHandle = gridView.FocusedRowHandle AndAlso e.Column Is _commandsColumn Then
            e.RepositoryItem = commandsEdit
        End If
    End Sub

    ' Allow only commandsColumn to be edited
    AddHandler gridView.ShowingEditor, Sub(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
    AddHandler commandsEdit.ButtonClick, Sub(s, e)
        Select Case e.Button.Caption
            Case "Edit"
                ' Start editing a row using EditForm
                gridView.CloseEditor()
                gridView.ShowEditForm()
            Case "Delete"
                ' Delete focused row
                gridView.DeleteRow(gridView.FocusedRowHandle)
        End Select
    End Sub

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.

csharp
RepositoryItemSpinEdit spinEdit = new RepositoryItemSpinEdit();
RepositoryItemCalcEdit calcEdit = new RepositoryItemCalcEdit();
grid.RepositoryItems.Add(spinEdit);
grid.RepositoryItems.Add(calcEdit);
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;
        else
            e.RepositoryItem = calcEdit;
    }
};
vb
Dim spinEdit As New RepositoryItemSpinEdit()
Dim calcEdit As New RepositoryItemCalcEdit()
grid.RepositoryItems.Add(spinEdit)
grid.RepositoryItems.Add(calcEdit)
gridView.Columns("Length").ShowButtonMode = ShowButtonModeEnum.ShowAlways

' Handle this event to assign editors to individual cells
AddHandler gridView.CustomRowCellEdit, Sub(sender, e)
    Dim view As GridView = TryCast(sender, GridView)
    If e.Column.FieldName = "Length" Then
        Dim boolVal As Boolean = CBool(view.GetRowCellValue(e.RowHandle, "Mark"))
        If boolVal Then
            e.RepositoryItem = spinEdit
        Else
            e.RepositoryItem = calcEdit
        End If
    End If
End Sub

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.

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

public Form1() {
    InitializeComponent();
    // 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;
    };
}
vb
Imports DevExpress.XtraGrid.Views.Grid
Imports DevExpress.XtraEditors.Repository

' Creates the repository items.
Dim spinEdit As New RepositoryItemSpinEdit()
Dim calcEdit As New RepositoryItemCalcEdit()
' Adds the repository items to the grid's RepositoryItems collection.
gridControl1.RepositoryItems.AddRange(New RepositoryItem() { spinEdit, calcEdit })
gridView.Columns("Length").ShowButtonMode = ShowButtonModeEnum.ShowAlways

' Handles the 'CustomRowCellEdit' event to assign different editors to cells in the 'Length' column.
AddHandler gridView.CustomRowCellEdit, Sub(sender, e)
    Dim view As GridView = TryCast(sender, GridView)
    If e.Column.FieldName = "Length" Then
        Dim boolVal As Boolean = CBool(view.GetRowCellValue(e.RowHandle, "Mark"))
        If boolVal Then
            e.RepositoryItem = spinEdit
        Else
                e.RepositoryItem = calcEdit
        End If
    End If
End Sub

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 following image shows the grid cell with an embedded DevExpress Chart control.

Run Demo: Embedded Gantt Run Demo: Embedded Chart

How to Display DevExpress Gantt Control in Grid Cells

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 uses ProgressBarControl to display numeric values in the Quantity column, and SpinEdit to edit cell values.

csharp
using DevExpress.XtraEditors.Repository;

public Form1() {
    InitializeComponent();
    // Creates two repository items.
    RepositoryItem editorForDisplay, editorForEditing;
    // Initializes the repository items.
    editorForDisplay = new RepositoryItemProgressBar();
    editorForEditing = new RepositoryItemSpinEdit();
    // Forces the grid to initialize its settings.
    gridControl1.ForceInitialize();
    // Adds the repository items to the grid's RepositoryItems collection.
    gridView1.GridControl.RepositoryItems.AddRange(
        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;
    };
}
vb
Imports DevExpress.XtraEditors.Repository

Public Sub New()
    InitializeComponent()
    ' Creates two repository items.
    Dim editorForDisplay, editorForEditing As RepositoryItem
    ' Initializes the repository items.
    editorForDisplay = New RepositoryItemProgressBar()
    editorForEditing = New RepositoryItemSpinEdit()
    ' Forces the grid to initialize its settings.
    gridControl1.ForceInitialize()
    ' Adds the repository items to the grid's RepositoryItems collection.
    gridView1.GridControl.RepositoryItems.AddRange(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.
    AddHandler gridView1.CustomRowCellEditForEditing, Sub(sender, e)
        If e.Column.FieldName = "Quantity" Then
            e.RepositoryItem = editorForEditing
        End If
    End Sub
End Sub

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

API to Manage Cell Editors

|

API

|

Description

| | --- | --- | |

BaseView.ShowEditor

|

Invokes the focused cell’s editor.

| |

BaseView.HideEditor

|

Closes the active editor and discards the changes made.

| |

BaseView.CloseEditor

|

Saves any changes made and closes the active editor.

| |

BaseView.PostEditor

|

Saves any changes made without closing the active editor.

| |

BaseView.ActiveEditor

|

Gets the active editor.

| |

ColumnView.ShownEditor

|

Fires when the grid activates an in-place editor.

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

csharp
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.
        editor.ShowPopup();
    }
}
vb
Imports DevExpress.XtraEditors
Imports DevExpress.XtraGrid.Views.Grid

Private Sub GridView1_ShownEditor(ByVal sender As Object, ByVal e As EventArgs)
    Dim view As GridView = TryCast(sender, GridView)
    If view.FocusedColumn = colOrderDate Then
        ' Specifies the current date.
        view.EditingValue = Date.Today
        ' Gets the active editor.
        Dim editor As DateEdit = TryCast(View.ActiveEditor, DateEdit)
        ' Invokes the dropdown.
        editor.ShowPopup()
    End If
End Sub

| |

ColumnView.HiddenEditor

|

Fires when an in-place editor closes.

The following example moves 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.

csharp
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;
    else
        view.FocusedRowHandle++;
    view.ShowEditor();
}
vb
Imports DevExpress.XtraEditors
Imports DevExpress.XtraGrid.Views.Grid

Private Sub GridView1_HiddenEditor(ByVal sender As Object, ByVal e As EventArgs)
    Dim view As GridView = TryCast(sender, GridView)
    If view.FocusedRowHandle = GridControl.NewItemRowHandle Then
        Return
    End If
    If view.FocusedRowHandle = view.RowCount - 1 Then
        view.FocusedRowHandle = 0
    Else
        view.FocusedRowHandle += 1
    End If
    view.ShowEditor()
End Sub

| |

OptionsBehavior.EditorShowMode

|

Specifies how a cell editor is activated by the mouse.

The following example displays editor buttons and let users click editor buttons on the first click:

csharp
using DevExpress.Utils;
using DevExpress.XtraGrid.Views.Base;

private void Form1_Load(object sender, EventArgs e) {
    gridView1.OptionsBehavior.EditorShowMode = EditorShowMode.MouseDown;
    gridView1.OptionsView.ShowButtonMode = ShowButtonModeEnum.ShowAlways;
}
vb
Imports DevExpress.Utils
Imports DevExpress.XtraGrid.Views.Base

Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs)
    gridView1.OptionsBehavior.EditorShowMode = EditorShowMode.MouseDown
    gridView1.OptionsView.ShowButtonMode = ShowButtonModeEnum.ShowAlways
End Sub

|

Disable Certain Cells (Cell Editors)

Disable All Cells

Disable a View’s OptionsBehavior.Editable option to disable all cells in the View.

csharp
gridView1.OptionsBehavior.Editable = false;
vb
gridView1.OptionsBehavior.Editable = False

Disable Cells in a Column

Disable a column’s OptionsColumn.AllowEdit to disable its cells.

csharp
gridView1.OptionsBehavior.Editable = true;
// Disables cells displayed in the PropertyA column.
gridView1.Columns["PropertyA"].OptionsColumn.AllowEdit = false;
vb
gridView1.OptionsBehavior.Editable = True
' Disables cells displayed in the PropertyA column.
gridView1.Columns["PropertyA"].OptionsColumn.AllowEdit = False

Enable a column’s OptionsColumn.ReadOnly setting to make its cells read-only (the OptionsColumn.AllowEdit property must be set to true ). The user can invoke the cell’s editor to copy its value, but cannot edit that value.

csharp
gridView1.OptionsBehavior.Editable = true;
gridView1.Columns["PropertyA"].OptionsColumn.AllowEdit = true;
// Makes cells in the PropertyA column read-only.
gridView1.Columns["PropertyA"].OptionsColumn.ReadOnly = true;
vb
gridView1.OptionsBehavior.Editable = True
gridView1.Columns["PropertyA"].OptionsColumn.AllowEdit = True
' Makes cells in the PropertyA column read-only.
gridView1.Columns["PropertyA"].OptionsColumn.ReadOnly = True

Run Demo: Disabled Mode

Disable Cells and Rows Based on a Condition

Use one of the following options to disable specific cells or data rows based on a condition:

  • Handle the ColumnView.ShowingEditor event and set the e.Cancel parameter to true to disable the processed cell based on a specific condition.

  • Use the Disabled Cell Behavior to disable cells in rows that meet a specific condition. Disabled cells are grayed-out and cannot be edited.

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.

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.

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

Note

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

Edit Form API

|

API

|

Description

| | --- | --- | |

GridOptionsBehavior.EditingMode

|

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

| |

GridView.ShowEditForm
GridView.HideEditForm

|

Allow you to display and hide the Edit Form.

| |

GridOptionsEditForm.ActionOnModifiedRowChange

|

Specifies whether to show confirmation dialogs when users modify records.

| |

GridOptionsEditForm.ShowUpdateCancelPanel

|

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

| |

GridOptionsEditForm.BindingMode

|

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.

| |

GridOptionsEditForm.FormCaptionFormat

|

Specifies the caption of a Floating Edit Form.

| |

GridView.EditFormShowing

|

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:

csharp
gridView.OptionsBehavior.EditingMode = GridEditingMode.EditForm;

gridView1.EditFormShowing += (s, e) => {
    e.Allow = e.RowHandle % 2 != 0; 
};
vb
gridView.OptionsBehavior.EditingMode = GridEditingMode.EditForm

AddHandler gridView1.EditFormShowing, Sub(s, e) e.Allow = e.RowHandle Mod 2 <> 0

Run Demo

|

Important

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.

csharp
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.
            dateEdit.Select();
            return;
        }
    }
};
vb
Imports DevExpress.XtraGrid.Views.Grid
' ...
gridView.OptionsBehavior.EditingMode = GridEditingMode.EditForm
Dim dateEdit As DateEdit = Nothing

AddHandler gridView.EditFormPrepared, Sub(s, e)
    ' The 'e.BindableControls' collection contains the editors in the Edit Form.
    For Each item As Control In e.BindableControls
        dateEdit = TryCast(item, DateEdit)
        If dateEdit IsNot Nothing Then
            ' Focuses the Date Editor.
            dateEdit.Select()
            Return
        End If
    Next item
End Sub

Run Demo: How to Access Editor in Edit Form

Note

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

Tip

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 all layout columns horizontally and three layout rows vertically.
  • PictureEdit editors span two layout columns horizontally and three layout rows vertically.

Tip

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

Edit Form API

|

API

|

Description

| | --- | --- | |

GridColumn.OptionsEditForm

|

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

| |

OptionsColumnEditForm.UseEditorColRowSpan

|

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.

| |

OptionsColumnEditForm.StartNewRow

|

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 SetBoundFieldName and SetBoundPropertyName methods 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.
csharp
using DevExpress.XtraGrid.Views.Grid;
// Custom Edit Form
public class AdvancedEditForm : EditFormUserControl {
    public AdvancedEditForm() {
        InitializeComponent();
        // 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(); 
}
vb
Imports DevExpress.XtraGrid.Views.Grid
' Custom Edit Form
Public Class AdvancedEditForm
  Inherits EditFormUserControl

    Public Sub New()
        InitializeComponent()
        ' Binds the 'EditValue' of the 'textEdit3' editor to the Price field.
        Me.SetBoundFieldName(textEdit3, "Price")
        Me.SetBoundPropertyName(textEdit3, "EditValue")
    End Sub
End Class

' 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)
    Dim detailCloneView As GridView = TryCast(e.View, GridView)
    If detailCloneView.LevelName = "Order_Details" Then
        detailCloneView.OptionsEditForm.CustomEditFormLayout = New AdvancedEditForm()
    End If

Run Demo: Custom Edit Form

Tip

How to implement CRUD operations in read-only data sources (WinForms Data Grid)

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 specifies a 10-digit phone mask.

csharp
var settings = repositoryItemTextEdit1.MaskSettings.Configure<MaskSettings.Numeric>();
settings.MaskExpression = "+1 (000) 000-0000";
repositoryItemTextEdit1.UseMaskAsDisplayFormat = true; // Optional
grid.RepositoryItems.Add(repositoryItemTextEdit1);
gridView.Columns["Phone"].ColumnEdit = repositoryItemTextEdit1;
vb
Dim settings = repositoryItemTextEdit1.MaskSettings.Configure(Of MaskSettings.Numeric)()
settings.MaskExpression = "+1 (000) 000-0000"
repositoryItemTextEdit1.UseMaskAsDisplayFormat = True ' Optional
grid.RepositoryItems.Add(repositoryItemTextEdit1)
gridView.Columns("Phone").ColumnEdit = repositoryItemTextEdit1

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 cell value.

The following diagram illustrates how the grid validates cell values:

  • 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 following code snippet checks the order shipping date to ensure that it is not earlier than the date this order was placed.

csharp
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";
        }
    }
}
vb
Private Sub GridView1_ValidatingEditor(ByVal sender As Object, ByVal e As BaseContainerValidateEditorEventArgs)
  Dim view As GridView = TryCast(sender, GridView)
  If view.FocusedColumn = colRequiredDate Then
      Dim requiredDate? As Date = CType(e.Value, Date?)
      Dim orderDate? As Date = CType(view.GetRowCellValue(view.FocusedRowHandle, colOrderDate), Date?)
      If requiredDate < orderDate Then
          e.Valid = False
          e.ErrorText = "Required Date is earlier than the order date"
      End If
  End If
End Sub

How to avoid duplicate values

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

csharp
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;
    else
        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)";
                return;
            }
        }
};

gridView.InvalidValueException += (s, e) => {
    e.ExceptionMode = ExceptionMode.DisplayError;
};
vb
AddHandler gridView.ValidatingEditor, Sub(s, e)
    Dim fieldName As String = String.Empty
    Dim view As GridView = TryCast(s, GridView)
    Dim ea As EditFormValidateEditorEventArgs = TryCast(e, EditFormValidateEditorEventArgs)
    If ea Is Nothing Then
        fieldName = view.FocusedColumn.FieldName
    Else
        fieldName = ea.Column.FieldName
    End If
    Dim rowCellValue As Integer
    Dim validatingCellValue As Integer = Convert.ToInt32(e.Value)
    If fieldName = "ID" Then
        ' Iterate through all data rows within GridView
        For rowHandle As Integer = 0 To view.DataRowCount - 1 
            ' Obtain the ID cell value of the processed row
            rowCellValue = Convert.ToInt32(view.GetRowCellValue(rowHandle, fieldName)) 
            If rowCellValue = validatingCellValue Then
                e.Valid = False
                e.ErrorText = "ID should be unique (ValidatingEditor)"
                Return
            End If
        Next rowHandle
    End If
End Sub

AddHandler gridView.InvalidValueException, Sub(s, e) e.ExceptionMode = ExceptionMode.DisplayError

Tip

The following in-place editors can post their value to the bound data source immediately after the value changes:

  • CheckEdit
  • ToggleSwitch
  • RadioGroup
  • TrackBarControl
  • RatingControl
  • PopupBaseEdit descendants

Use the editor’s InplaceModeImmediatePostChanges property to control this behavior. The WindowsFormsSettings.InplaceEditorUpdateMode property allows you to control update behavior globally.

Validate Rows

Note

Data objects must implement IEditableObject to discard changes made to cell values.

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).

The following diagram illustrates how the grid validates data rows:

  • 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 changes.

  • 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).

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

namespace DXApplication {
    public partial class Form1 : DevExpress.XtraEditors.XtraForm {
        DXErrorProvider errorProvider;
        public Form1() {
            InitializeComponent();
            // 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" }
            };
        }
    }
}
vb
Imports DevExpress.XtraEditors.DXErrorProvider

Namespace DXApplication50
  Partial Public Class Form1
    Inherits DevExpress.XtraEditors.XtraForm

    Private errorProvider As DXErrorProvider
    Public Sub New()
      InitializeComponent()
      Dim records As List(Of MyRecord) = MyRecord.InitData()
      gridControl1.DataSource = records
      errorProvider = New DXErrorProvider(Me)
      errorProvider.DataSource = records
    End Sub
  End Class
  Public Class MyRecord
    Inherits IDXDataErrorInfo

    Public Property FirstName() As String
    Public Property LastName() As String
    Public Sub GetPropertyError(ByVal propertyName As String, ByVal info As ErrorInfo)
      If propertyName = "FirstName" AndAlso FirstName = "" OrElse propertyName = "LastName" AndAlso LastName = "" Then
        info.ErrorText = String.Format("The {0} field cannot be empty", propertyName)
      End If
    End Sub
    Public Sub GetError(ByVal info As ErrorInfo)
    End Sub
    Public Shared Function InitData() As List(Of MyRecord)
      Return New List(Of MyRecord)() From {
        New MyRecord() With {.FirstName = "Mike", .LastName = "Brown"},
        New MyRecord() With {.FirstName = "Sandra", .LastName = "Smith"},
        New MyRecord() With {.FirstName = "Andy", .LastName = "Muller"}
      }
    End Function
  End Class
End Namespace

The following code snippet obtains input errors in the “Last Name” column when handling the ValidateRow event:

csharp
using DevExpress.XtraEditors.DXErrorProvider;
using DevExpress.XtraEditors.Controls;

ErrorInfo errorInfo;
public Form1() {
    InitializeComponent();
    errorInfo = new ErrorInfo();
    gridView1.ValidateRow += gridView1_ValidateRow;
    gridView1.InvalidRowException += gridView1_InvalidRowException;
    //...
}
void gridView1_ValidateRow(object sender, ValidateRowEventArgs e) {
    errorInfo.ErrorText = string.Empty;
    errorInfo.ErrorType = ErrorType.None;

    (e.Row as IDXDataErrorInfo).GetPropertyError("LastName", errorInfo);
    e.Valid = errorInfo.ErrorType != ErrorType.Critical;
}
void gridView1_InvalidRowException(object sender, InvalidRowExceptionEventArgs e) {
    e.ExceptionMode = ExceptionMode.NoAction;
}
vb
Imports DevExpress.XtraEditors.DXErrorProvider
Imports DevExpress.XtraEditors.Controls

Public Class Form1
    Private errorInfo As ErrorInfo

    Public Sub New()
        InitializeComponent()
        errorInfo = New ErrorInfo()
        AddHandler gridView1.ValidateRow, AddressOf gridView1_ValidateRow
        AddHandler gridView1.InvalidRowException, AddressOf gridView1_InvalidRowException
        '...
    End Sub

    Private Sub gridView1_ValidateRow(sender As Object, e As ValidateRowEventArgs)
        errorInfo.ErrorText = String.Empty
        errorInfo.ErrorType = ErrorType.None

        CType(e.Row, IDXDataErrorInfo).GetPropertyError("LastName", errorInfo)
        e.Valid = errorInfo.ErrorType <> ErrorType.Critical
    End Sub

    Private Sub gridView1_InvalidRowException(sender As Object, e As InvalidRowExceptionEventArgs)
        e.ExceptionMode = ExceptionMode.NoAction
    End Sub
End Class

View Example: Validate rows using IDXDataErrorInfo

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.

csharp
void gridView1_RowUpdated(object sender, RowObjectEventArgs e) {
    // Use data source API to save changes.
}
vb
Sub gridView1_RowUpdated(ByVal sender As Object, ByVal e As RowObjectEventArgs)
    ' Use data source API to save changes.
End Sub

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

Note

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.

csharp
void gridView1_CellValueChanged(object sender, CellValueChangedEventArgs e) {
    ColumnView view = sender as ColumnView;  
    view.CloseEditor();  
    if(view.UpdateCurrentRow()) {  
        // Use data source API to save changes.
    }
}
vb
Sub gridView1_CellValueChanged(ByVal sender As Object, ByVal e As CellValueChangedEventArgs)
    Dim view As ColumnView = TryCast(sender, ColumnView)
    view.CloseEditor()
    If view.UpdateCurrentRow() Then
        ' Use data source API to save changes.
    End If
End Sub

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

Tip

If you need to immediately post changes to the data source without moving the focus out of the cell, call the view’s PostEditor() method in the repository item’s EditValueChanged event handler:

csharp
repositoryItemCheckedComboBoxEdit1.EditValueChanged += (s, e) => {
    gridControl1.FocusedView.PostEditor();
};
vb
AddHandler repositoryItemCheckedComboBoxEdit1.EditValueChanged, Sub(s, e)
  gridControl1.FocusedView.PostEditor()
End Sub

Display Edit Buttons in Data Cells

This example assigns a RepositoryItemButtonEdit to a grid column and customizes related settings.

View Example

Customize the Cell Editor Button Caption Using the CustomRowCellEdit Event

This example handles the GridView.CustomRowCellEdit event to display cell values in the first button of a Button Editor used to edit column values.

View Example

Display Colored Progress Bars in Cells

This example uses two ways to display colored progress bars in cells:

View Example

Display Rich Text in Data Cells and Edit Cell Values in a Popup Window

This example uses different data editors to display and edit cell values. The RichEditControl is used to edit RTF data (it is displayed within a popup window). The RepositoryItemRichTextEdit is used to display RTF data in data cells.

View Example

Filter a Lookup Column based on a Value in Another Lookup Column (Edit Form)

The example implements two ways to address this task:

  • Filter a single LookUpEdit’s data source based on the first LookUp’s value.
  • Assign different sources to LookUpEdit based on the first LookUp’s value.

View Example

Hide a Check Box from Specific Grid Cells

This example creates an empty repository item and handles the CustomRowCellEdit event to assign the repository item to grid cells based on a condition.

View Example

Simultaneous editing of multiple cell values

This example applies a new value to all selected cells.

View Example

Use a Color Editor to Edit Colors that are Stored as Strings

The WinForms ColorEdit is designed to work with values of the Color type. In this example, the data source stores colors as strings in the “ColorString” field. The example creates an unbound column and uses the Color Editor to display and edit “ColorString” field values.

View Example

Cheat Sheets and Best Practices

See Also

Error Notification Support for Data Sources

Internal ErrorInfo Support

Add and Remove Rows

IDXDataErrorInfo