Skip to main content
A newer version of this page is available. .

Modify and Validate Cell Values

  • 16 minutes to read

In-Place Editors

Cell Values

Edit data in a separate form

Manage End-User Input

Default In-Place Editors

Data Grid supports data editing out-of-the box. To edit a cell value at runtime, an end-user must focus it and press Enter, or double-click this cell. To discard edits, press Esc while editing.

Columns utilize DevExpress Editors, and optionally, more complex DevExpress controls to display and edit data source records. Columns automatically choose editors depending on the column data type. For instance, if a column displays dates, it will utilize the DateEdit in-place editor.

Data Grid - Date Edit In-Place Editor

Note that grid uses repository items from which editors are created when a cell activates. If a cell is inactive, its editor does not exist.

Demos: Inplace Cell Editors | Show buttons in grid cells

Change Default In-Place Editors at Design Time

To modify an in-place editor for a Data Grid column, invoke drop-down menu for the GridColumn.ColumnEdit property and create a new editor (or choose an existing one). This property can be accessed from the column smart tag.

Data Grid - Column Edit Smart Tag

The “In-place Editor Repository” tab of a Data Grid Designer provides a centralized access to all in-place editors. Here you can add new editors, as well as modify and remove existing ones.

Data Grid - Repository Items Designer

Change Default In-Place Editors in Code

DevExpress editors have corresponding repository items - objects that store main editor properties. A repository item is a core from which a full editor can be generated. For instance, a RepositoryItemSpinEdit object is the core of a SpinEdit editor. For in-place editing in the Data Grid, you need to create these repository items and assign them to GridColumn.ColumnEdit properties. Alternatively, if you need to specify an in-place editor for a specific cell, and not an entire column, handle the GridView.CustomRowCellEdit event. Note that any repository item you create in code must be manually added to the grid control’s EditorContainer.RepositoryItems collection.

The code below illustrates how to utilize a ProgressBarControl as an in-place editor for the integer “Relevance” grid column. End-users can tap or hold numpad “+” and “-“ keys to modify these integer values. To test this code sample, run the Dynamically Assigned Editors demo.


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 repository item
colRelevance.ColumnEdit = ieProgress;
//or
private void GridView1_CustomRowCellEdit(object sender, CustomRowCellEditEventArgs e) {
    if (e.Column == colRelevance) e.RepositoryItem = ieProgress;
}

//handle + and - keys press
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;
    }
}

Demos: Assign in-place editors (repository items) | Assign in-place editors dynamically

Use Non-Editor Controls as In-Place Editors

The RepositoryItemAnyControl allows you to embed any static control into a grid cell. The figure below illustrates an embedded Chart Control.

Data Grid - In-Place Chart Control

In order to embed a control, it must implement the DevExpress.XtraEditors.CustomEditor.IAnyControlEdit interface. The Gauge Control implements this interface out-of-the-box. To embed other controls you need to implement it manually.

Embedded Gauge Control: Demo | Example

Embedded Chart Control: Demo | Example

Display and Edit In-Place Editors

By default, in-place editors are used for both presenting data and editing records. If needed, you can use separate in-place editors for both tasks. To do so, handle the GridView.CustomRowCellEditForEditing event. In the code sample below, a numeric column utilizes ProgressBarControl in-place editors to display data. When end-users focus cells, SpinEdit editors replace progress bars, which provide a more straightforward way of modifying cell values.


using DevExpress.XtraEditors.Repository;

// In-place editors used in display and edit modes respectively.
RepositoryItem editorForDisplay, editorForEditing;

private void Form1_Load(object sender, EventArgs e) {
    // Initialize the editors and assign the default editor to a column.
    editorForDisplay = new RepositoryItemProgressBar();
    editorForEditing = new RepositoryItemSpinEdit();
    gridView1.GridControl.RepositoryItems.AddRange( 
      new RepositoryItem[] { editorForDisplay, editorForEditing });
    gridView1.Columns["Quantity"].ColumnEdit = editorForDisplay;
}

// Provide the editor for in-place editing.
private void gridView1_CustomRowCellEditForEditing(object sender, 
  CustomRowCellEditEventArgs e) {
    if (e.Column.FieldName == "Quantity")
        e.RepositoryItem = editorForEditing;
}

Demo: Override the default in-place editor for certain cells

Manage In-Place Editors in Code


using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraEditors;
//. . .
gridView1.ShownEditor += GridView1_ShownEditor;
//. . .
private void GridView1_ShownEditor(object sender, EventArgs e) {
    GridView View = sender as GridView;
    if (View.FocusedColumn == colOrderDate) {
        // adding the current date 
        View.EditingValue = DateTime.Today;
        // obtaining the active editor 
        DateEdit editor = View.ActiveEditor as DateEdit;
        // invoking the editor's popup window 
        editor.ShowPopup();
    }
}
  • ColumnView.HiddenEditor - fires whenever an in-place editor closes. In the sample below, focus automatically moves to the cell below after an editor for the current cell closes. This allows your end-users to quickly change values of multiple cells that belong to the same column by entering new values and pressing Enter (or Escape). This code will not be executed when end-users work with a New Item Row.

using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraEditors;
//. . .
gridView1.HiddenEditor += GridView1_HiddenEditor;
//. . .
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();
}

Retrieve and Modify Cell Values in Code

To retrieve cell values, utilize the following API.

The API below allows you to change cell values in code.

Changing a cell value raises the ColumnView.CellValueChanged event.

The following code samples illustrate this API.

Example 1: Get values of the “ID” column within the third data row (row handle equals 2).


string cellValue;
cellValue = gridView1.GetRowCellValue(2, "ID").ToString();

Example 2: Obtain text of a focused cell.


string cellValue = gridView1.GetFocusedDisplayText();

Example 3: Obtain the value of a cell that belongs to the focused row and the first column.


System.Data.DataRow row = gridView1.GetDataRow(gridView1.FocusedRowHandle);
string cellValue = row[0].ToString();

Example 4: Change the focused cell’s value.


gridView1.SetRowCellValue(gridView1.FocusedRowHandle, gridView1.FocusedColumn, "New Value");

Example 5: Set the value of a cell that belongs to the focused row and the first Data Grid column.


System.Data.DataRow row = gridView1.GetDataRow(gridView1.FocusedRowHandle);
row[0] = "New Value";

Edit Form

Instead of in-place data editing, end-users can modify grid records by using an Edit Form. To invoke this form, double-click a grid row at runtime or press the Enter or F2 key.

Data Grid - Inline Edit Form

For regular Views you can select one of three available Edit Form display modes:

  • a floating modal form (default mode);
  • an in-place form displayed below a grid row that is being edited;
  • an in-place form displayed instead of the edited row.

Detail Views do not support in-line edit forms.

Related API

Demos: Inline Edit Form | Prevent the Edit Form from showing | Access an editor within the Edit Form

Modify Edit Form Layout

Default Edit Form layout is built according to the following rules:

  • Edit Form displays an editor for every visible editable column;
  • in case a Grid Column uses different editor types to present and edit cell data, Edit Form utilizes ones that are used in editing records;
  • an Edit Form client area has a table layout with three columns; every editor (except for MemoEdit and PictureEdit editors) occupies one single cell;
  • 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.

To modify this default layout, invoke the Data Grid Designer and switch to its “Edit Form Designer” tab. Here you can modify layout settings of every column editor.

Data Grid - Edit Form Designer

Related API

Custom Edit Form

You can create your own User Control and utilize it instead of a default Edit Form.

  1. Create a User Control and inherit it from the EditFormUserControl class.
  2. If you have partial classes for this User Control, they must inherit the EditFormUserControl class as well.
  3. Design your custom User Control UI.
  4. Use the BoundFieldName and BoundPropertyName extender properties provided by the parent class to bind editors to data source fields.
  5. Assign an instance of the custom edit form to the Data Grid GridOptionsEditForm.CustomEditFormLayout property.
  6. To be able to use this custom form in detail Views, assign separate form instances to each detail View.

using DevExpress.XtraGrid.Views.Grid;
//custom edit form
public class AdvancedEditForm : EditFormUserControl {
    public AdvancedEditForm() {
        InitializeComponent();
        //bind the EditValue of the textEdit3 editor to the "Price" data field
        this.SetBoundFieldName(textEdit3, "Price");
        this.SetBoundPropertyName(textEdit3, "EditValue");
    }
}

//use the custom edit form in non-master-detail Data Grids
gridView1.OptionsEditForm.CustomEditFormLayout = new AdvancedEditForm();

//use custom edit forms for detail Views
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(); 
}

Demos: Custom Edit Form | Inline Edit Form

Prevent End-Users from Modifying Cell Values

To disable the editing of cell values at runtime, utilize one of the following approaches:

  • disable the ColumnViewOptionsBehavior.Editable option;
  • enable the OptionsColumn.ReadOnly setting;
  • disable the OptionsColumn.AllowEdit and OptionsColumn.AllowFocus options;
  • handle the ColumnView.ShowingEditor event and set its Cancel parameter to true. For instance, the code snippet below prohibits editing records whose “Country” field equals “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;
    }
    

These settings affect only your end-users and do not prevent you from modifying cell values in code.

Demos: Non editable mode | Prohibit editing certain GridView’s cells

Validate End-User Input (Per Cell)

A cell is validated when a user has finished editing a value and presses Enter or moves focus to another cell within the same row. You can also forcibly trigger validation by calling the BaseView.PostEditor method in code. The diagram below illustrates this validation process.

Data Grid - Validation - Cell Validation

  • BaseView.ValidatingEditor - handle this event to check whether or not a new cell value is correct and set the boolean e.Valid parameter accordingly. End-users are unable to leave a cell with an incorrect value until the error is fixed or the “Esc” key is pressed to undo changes.

  • BaseView.InvalidValueException - raises if the e.Valid parameter of the previous event has been set to false and allows you to specify how the Data Grid responds to an invalid value. See the ExceptionMode enumerator values to see what options are available.

  • If the ExceptionMode parameter is set to NoAction, cells do not accept invalid values without notifying users. Use this approach if you want to implement custom notifications. For instance, you can provide default error icons for multiple columns at once by calling the ColumnView.SetColumnError method.

The code sample below checks the order shipping date, which cannot be earlier than the date this order was placed.

Data Grid - Validation Dates


private void GridView1_ValidatingEditor(object sender, DevExpress.XtraEditors.Controls.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";
        }
    }
}

The Data Validation demo utilizes a different cell validation approach and employs the GridView.RowCellStyle event to highlight cells with values that are wrong initially, not after an end-user has modified them.

Demos: Data Validation | Validate the active editor’s value

Row Validation

With the row validation feature, the Data Grid delays checking cell values to the point when a user moves focus to another row. This can be useful when each particular cell is valid, but the entire row with these values is incorrect. To manually trigger row validation, call the ColumnView.UpdateCurrentRow method.

Data Grid - Validation - Row Diagram

  • ColumnView.ValidateRow, ColumnView.InvalidRowException - similarly to per-cell validation, these events allow you to validate new cell values and respond to invalid ones. If new cell values do not pass validation, end-users are kept on the current row to either correct all errors, or press Esc and undo the changes. Note that to revert row cell values back to correct ones, data source objects must implement the IEditableObject interface.

  • If a row is invalid, the Data Grid displays a message by default, permitting users to either correct or discard new values. You can suppress this default notification and call the ColumnView.SetColumnError method to manually mark specific cells (or the entire row) as invalid.

In the Data Validation demo, the ValidateRow event is handled to calculate values of the “Sub Total” column cells based on the “Unit Price”, “Quantity” and “Discount” column cells. Negative subtotal values are not accepted.

Data Grid - Validate Row Demo


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;
    }
}

Demos: Data Validation | Validate row data on losing focus

See Also