| |
 |
Cell Values, Editors, and Validation
Cell Values
Cell Editors
Edit Data in a Separate Form
Manage End-User Input

Read and Modify Cell Values in Code
Changing a cell value raises the ColumnView.CellValueChanged event.
The following code samples illustrate this API.
The code below retrieves the value of a cell that belongs to the "ID" column and the third data row (row handle equals 2).
C# |
string cellValue;
cellValue = gridView1.GetRowCellValue(2, "ID").ToString();
|
VB |
Dim CellValue As String
CellValue = GridView1.GetRowCellValue(2, "ID")
|
This code returns the text displayed inside the currently focused cell.
C# |
string cellValue = gridView1.GetFocusedDisplayText();
|
VB |
Dim cellValue As String = GridView1.GetFocusedDisplayText()
|
This example changes the value of the focused cell.
C# |
gridView1.SetRowCellValue(gridView1.FocusedRowHandle, gridView1.FocusedColumn, "New Value");
gridView1.SetFocusedValue("New Value");
|
VB |
gridView1.SetRowCellValue(gridView1.FocusedRowHandle, gridView1.FocusedColumn, "New Value")
gridView1.SetFocusedValue("New Value")
|
Grid cell editors wait for a user to move focus to another cell or row before their new value is accepted. The code below forces editors to immediatelly update their values.
C# |
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
|
In the Change column cell values based on other cell values demo checkboxes under the "Mark" column are automatically checked if you enter "Length" more than 10, and cleared otherwise.
C# |
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
|

Cell Editors
Default Cell Editors
Data Grid supports in-place 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 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.

All DevExpress Editors contain related repository items. For instance, a SpinEdit editor contains a RepositoryItemSpinEdit object. Repository items are cores that store a set of properties required to generate a fully-fledged editor. You can access an editor's repository item through the BaseEdit.Properties property.
All inactive Grid cells contain repository items. When a user clicks a cell to edit its value, a real editor is created from this repository item. After all edits are done and the cell is deselected, its editor is destroyed again. This means unless Grid is in edit mode, no fully initialized cell editors exist. This technique greatly improves the Data Grid performance.

Demos: Inplace Cell Editors | Show buttons in grid cells
Replace Default Cell 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.

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.

Replace Default Cell Editors in Code
To use custom editors for column cells, assign related repository items to the GridColumn.ColumnEdit property. The Assign in-place editors (repository items) demo illustrates how to replace standard checkboxes for the "Mark" column with ToggleSwitch editors.
C# |
RepositoryItemToggleSwitch edit = new RepositoryItemToggleSwitch();
gridControl.RepositoryItems.Add(edit);
gridView.Columns["Mark"].ColumnEdit = edit;
|
VB |
Dim edit As New RepositoryItemToggleSwitch()
gridControl.RepositoryItems.Add(edit)
gridView.Columns("Mark").ColumnEdit = edit
|
If you need to specify an in-place editor for a specific cell rather than 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.
C# |
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraEditors.Repository;
RepositoryItemProgressBar ieProgress = new RepositoryItemProgressBar();
gridControl1.RepositoryItems.Add(ieProgress);
ieProgress.KeyPress += IeProgress_KeyPress;
colRelevance.ColumnEdit = ieProgress;
private void GridView1_CustomRowCellEdit(object sender, CustomRowCellEditEventArgs e) {
if (e.Column == colRelevance) e.RepositoryItem = ieProgress;
}
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
Private ieProgress As New RepositoryItemProgressBar()
gridControl1.RepositoryItems.Add(ieProgress)
Private ieProgress.KeyPress += AddressOf IeProgress_KeyPress
colRelevance.ColumnEdit = ieProgress
private void GridView1_CustomRowCellEdit(Object sender, CustomRowCellEditEventArgs e)
If e.Column = colRelevance Then
e.RepositoryItem = ieProgress
End If
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
|
The Cell commands to edit and delete rows demo has the "Commands" column with a ButtonEdit cell editor. The editor has two buttons: "Edit" invokes the Edit Form, "Delete" removes the current row.

C# |
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())});
GridColumn _commandsColumn = gridView.Columns.AddField("Commands");
_commandsColumn.UnboundType = UnboundColumnType.Object;
_commandsColumn.Visible = true;
_commandsColumn.Width = 100;
_commandsColumn.OptionsEditForm.Visible = DevExpress.Utils.DefaultBoolean.False;
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;
};
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;
commandsEdit.ButtonClick += (s, e) => {
switch (e.Button.Caption) {
case "Edit":
gridView.CloseEditor();
gridView.ShowEditForm();
break;
case "Delete":
gridControl.BeginInvoke(new MethodInvoker(() => { gridView.DeleteRow(gridView.FocusedRowHandle); }));
break;
}
};
|
VB |
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())
})
Dim _commandsColumn As GridColumn = gridView.Columns.AddField("Commands")
_commandsColumn.UnboundType = UnboundColumnType.Object
_commandsColumn.Visible = True
_commandsColumn.Width = 100
_commandsColumn.OptionsEditForm.Visible = DevExpress.Utils.DefaultBoolean.False
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
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
AddHandler commandsEdit.ButtonClick, Sub(s, e)
Select Case e.Button.Caption
Case "Edit"
gridView.CloseEditor()
gridView.ShowEditForm()
Case "Delete"
gridControl.BeginInvoke(New MethodInvoker(Sub() gridView.DeleteRow(gridView.FocusedRowHandle)))
End Select
End Sub
|
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.
C# |
RepositoryItemSpinEdit spinEdit = new RepositoryItemSpinEdit();
RepositoryItemCalcEdit calcEdit = new RepositoryItemCalcEdit();
gridView.Columns["Length"].ShowButtonMode = ShowButtonModeEnum.ShowAlways;
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()
gridView.Columns("Length").ShowButtonMode = ShowButtonModeEnum.ShowAlways
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
|
The code sample below creates two identical RepositoryItemButtonEdit editors with buttons that copy or remove a cell value. The second editor buttons are disabled. If a checkbox under the "Mark" column is currently checked, an editor with enabled buttons becomes this cell's editor. Otherwise, when the "Mark" checkbox is clear, the editor with disabled buttons is assigned.

C# |
gridView.OptionsView.ShowButtonMode = ShowButtonModeEnum.ShowAlways;
RepositoryItemButtonEdit riButtonEditEnabled = new RepositoryItemButtonEdit();
riButtonEditEnabled.Buttons.Clear();
riButtonEditEnabled.Buttons.Add(new EditorButton(ButtonPredefines.Plus, "Copy cell value"));
riButtonEditEnabled.Buttons.Add(new EditorButton(ButtonPredefines.Delete, "Clear this cell"));
RepositoryItemButtonEdit riButtonEditDisabled = new RepositoryItemButtonEdit();
riButtonEditDisabled.Assign(riButtonEditEnabled);
riButtonEditDisabled.Buttons.ToList<EditorButton>().ForEach(button => button.Enabled = false);
gridView.CustomRowCellEdit += (s, e) => {
if (e.Column.FieldName == "Notes") {
GridView view = s as GridView;
bool actionsAvailable = Convert.ToBoolean(view.GetRowCellValue(e.RowHandle,"Mark"));
e.RepositoryItem = actionsAvailable ? riButtonEditEnabled : riButtonEditDisabled;
}
};
|
VB |
gridView.OptionsView.ShowButtonMode = ShowButtonModeEnum.ShowAlways
Dim riButtonEditEnabled As New RepositoryItemButtonEdit()
riButtonEditEnabled.Buttons.Clear()
riButtonEditEnabled.Buttons.Add(New EditorButton(ButtonPredefines.Plus, "Copy cell value"))
riButtonEditEnabled.Buttons.Add(New EditorButton(ButtonPredefines.Delete, "Clear this cell"))
Dim riButtonEditDisabled As New RepositoryItemButtonEdit()
riButtonEditDisabled.Assign(riButtonEditEnabled)
riButtonEditDisabled.Buttons.ToList().ForEach(Sub(button) button.Enabled = False)
AddHandler gridView.CustomRowCellEdit, Sub(s, e)
If e.Column.FieldName = "Notes" Then
Dim view As GridView = TryCast(s, GridView)
Dim actionsAvailable As Boolean = Convert.ToBoolean(view.GetRowCellValue(e.RowHandle,"Mark"))
e.RepositoryItem = If(actionsAvailable, riButtonEditEnabled, riButtonEditDisabled)
End If
End Sub
|
Demos: Assign in-place editors (repository items) | Assign in-place editors dynamically
Use Any Control as a Cell Editor
The RepositoryItemAnyControl allows you to embed any static control into a grid cell. The figure below illustrates an embedded 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
Use Different Controls to Display and Edit Cell Values
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.
C# |
using DevExpress.XtraEditors.Repository;
RepositoryItem editorForDisplay, editorForEditing;
private void Form1_Load(object sender, EventArgs e) {
editorForDisplay = new RepositoryItemProgressBar();
editorForEditing = new RepositoryItemSpinEdit();
gridView1.GridControl.RepositoryItems.AddRange(
new RepositoryItem[] { editorForDisplay, editorForEditing });
gridView1.Columns["Quantity"].ColumnEdit = editorForDisplay;
}
private void gridView1_CustomRowCellEditForEditing(object sender,
CustomRowCellEditEventArgs e) {
if (e.Column.FieldName == "Quantity")
e.RepositoryItem = editorForEditing;
}
|
VB |
Imports DevExpress.XtraEditors.Repository
Dim editorForDisplay, editorForEditing As RepositoryItem
Private Sub Form1_Load(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles MyBase.Load
editorForDisplay = New RepositoryItemProgressBar()
editorForEditing = New RepositoryItemSpinEdit()
gridView1.GridControl.RepositoryItems.AddRange( _
New RepositoryItem() {editorForDisplay, editorForEditing})
gridView1.Columns("Quantity").ColumnEdit = editorForDisplay
End Sub
Private Sub gridView1_CustomRowCellEditForEditing(ByVal sender As System.Object, _
ByVal e As DevExpress.XtraGrid.Views.Grid.CustomRowCellEditEventArgs) _
Handles gridView1.CustomRowCellEditForEditing
If e.Column.FieldName = "Quantity" Then
e.RepositoryItem = editorForEditing
End If
End Sub
|
Demo: Override the default in-place editor for certain cells
Manage Cell Editors in Code
API
|
Description
|
---|
BaseView.ShowEditor
|
Invokes the focused cell's editor
|
BaseView.HideEditor
|
Closes the currently active editor and discards any changes
|
BaseView.CloseEditor
|
Saves any changes made and closes the currently active editor
|
BaseView.PostEditor
|
Saves any changes made without closing the currently active editor
|
BaseView.ActiveEditor
|
Retrieves the currently active editor
|
ColumnView.ShownEditor
|
Fires whenever an in-place editor activates. The code below automatically sets the current date and opens the DateEdit popup when end-users activate the "Order Date" column editor.
C# |
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) {
View.EditingValue = DateTime.Today;
DateEdit editor = View.ActiveEditor as DateEdit;
editor.ShowPopup();
}
}
|
VB |
Imports DevExpress.XtraGrid.Views.Grid
Imports DevExpress.XtraEditors
Private gridView1.ShownEditor += AddressOf GridView1_ShownEditor
Private Sub GridView1_ShownEditor(ByVal sender As Object, ByVal e As EventArgs)
Dim View As GridView = TryCast(sender, GridView)
If View.FocusedColumn = colOrderDate Then
View.EditingValue = Date.Today
Dim editor As DateEdit = TryCast(View.ActiveEditor, DateEdit)
editor.ShowPopup()
End If
End Sub
|
|
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.
C# |
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();
}
|
VB |
Imports DevExpress.XtraGrid.Views.Grid
Imports DevExpress.XtraEditors
Private gridView1.HiddenEditor += AddressOf GridView1_HiddenEditor
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
|
|

Edit Data in a Separate Form
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.

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
API
|
Description
|
---|
GridOptionsBehavior.EditingMode
|
Allows you turn on the Edit Form and select its display mode.
|
GridView.ShowEditForm GridView.HideEditForm
|
Call these methods to manually display and hide an Edit Form.
|
GridOptionsEditForm.ActionOnModifiedRowChange
|
Specifies whether to show confirmation dialogs when end-users modify records.
|
GridOptionsEditForm.ShowUpdateCancelPanel
|
Gets or sets whether or not the "Update" and "Cancel" buttons should be displayed. When these buttons are hidden, end-users can still utilize hotkeys to save (Ctrl+Enter) or discard (Escape) changes.
|
GridOptionsEditForm.BindingMode
|
Specifies whether to pass changes to a Data Grid immediately after an end-user moves focus to another Edit Form field, or only after all changes have been accepted.
|
GridOptionsEditForm.FormCaptionFormat
|
Allows you to modify a caption of a floating Edit Form.
|
GridView.EditFormShowing
|
Fires when the Edit Form is about to be shown, and allows you to forcibly hide the Edit Form when you do not want users to edit specific cell values. In the Prevent the Edit Form from Showing demo you cannot edit odd rows.
C# |
gridView.OptionsBehavior.EditingMode = GridEditingMode.EditForm;
gridView.EditFormShowing += (s, e) => {
if (e.RowHandle % 2 == 0)
e.Allow = false;
};
|
VB |
gridView.OptionsBehavior.EditingMode = GridEditingMode.EditForm
AddHandler gridView.EditFormShowing, Sub(s, e)
If e.RowHandle Mod 2 = 0 Then
e.Allow = False
End If
End Sub
|
|
Demos: Inline Edit Form | Prevent the Edit Form from showing | Access an editor within the Edit Form
Access Editors in the Edit Form
When an Edit Form is initialized and is about to be shown, the GridView.EditFormPrepared event raises. You can handle this event to access any Edit Form editor and modify its settings. The Access an Editor Within the Edit Form demo illustrates how to find the DateEdit editor and focus it.
C# |
gridView.OptionsBehavior.EditingMode = GridEditingMode.EditForm;
DateEdit dateEdit = null;
gridView.EditFormPrepared += (s, e) => {
foreach (Control item in e.BindableControls) {
dateEdit = item as DateEdit;
if (dateEdit != null) {
gridControl.BeginInvoke(new MethodInvoker(() => { dateEdit.Focus(); }));
return;
}
}
};
|
VB |
gridView.OptionsBehavior.EditingMode = GridEditingMode.EditForm
Dim dateEdit As DateEdit = Nothing
AddHandler gridView.EditFormPrepared, Sub(s, e)
For Each item As Control In e.BindableControls
dateEdit = TryCast(item, DateEdit)
If dateEdit IsNot Nothing Then
gridControl.BeginInvoke(New MethodInvoker(Sub() dateEdit.Focus()))
Return
End If
Next item
End Sub
|
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.

Related API
Create Custom Edit Forms
You can create your own User Control and utilize it instead of a default Edit Form.
- Create a User Control and inherit it from the EditFormUserControl class.
- If you have partial classes for this User Control, they must inherit the EditFormUserControl class as well.
- Design your custom User Control UI.
- Use the BoundFieldName and BoundPropertyName extender properties provided by the parent class to bind editors to data source fields.
- Assign an instance of the custom edit form to the Data Grid GridOptionsEditForm.CustomEditFormLayout property.
- To be able to use this custom form in detail Views, assign separate form instances to each detail View.
C# |
using DevExpress.XtraGrid.Views.Grid;
public class AdvancedEditForm : EditFormUserControl {
public AdvancedEditForm() {
InitializeComponent();
this.SetBoundFieldName(textEdit3, "Price");
this.SetBoundPropertyName(textEdit3, "EditValue");
}
}
gridView1.OptionsEditForm.CustomEditFormLayout = new AdvancedEditForm();
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
Public Class AdvancedEditForm
Inherits EditFormUserControl
Public Sub New()
InitializeComponent()
Me.SetBoundFieldName(textEdit3, "Price")
Me.SetBoundPropertyName(textEdit3, "EditValue")
End Sub
End Class
gridView1.OptionsEditForm.CustomEditFormLayout = New AdvancedEditForm()
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
|
Demos: Custom Edit Form | Inline Edit Form

Manage End-User Input
Use Masks to Limit Data Input
Since DevExpress editors support Masks, you can prevent a user from entering invalid characters. The sample below illustrates how to allow users to enter 10-digit phone numbers with the automatically added "+1" country code.
C# |
repositoryItemTextEdit2.Mask.EditMask = "+1 (000) 000-00-00";
repositoryItemTextEdit2.Mask.MaskType = DevExpress.XtraEditors.Mask.MaskType.Numeric;
repositoryItemTextEdit1.Mask.UseMaskAsDisplayFormat = true;
gridView.Columns["Phone"].ColumnEdit = repositoryItemTextEdit2;
|
VB |
repositoryItemTextEdit2.Mask.EditMask = "+1 (000) 000-00-00"
repositoryItemTextEdit2.Mask.MaskType = DevExpress.XtraEditors.Mask.MaskType.Numeric
repositoryItemTextEdit1.Mask.UseMaskAsDisplayFormat = True
gridView.Columns("Phone").ColumnEdit = repositoryItemTextEdit2
|
Make Certain Grid Cells Non-Editable
To prevent users from editing cell values at runtime, utilize one of the following approaches:
You can also check the Read-only mode for certain cells demo where you cannot edit the "ID" column cells for every even row.
C# |
gridView.ShownEditor += (s, e) => {
GridView view = s as GridView;
view.ActiveEditor.Properties.ReadOnly = gridView.FocusedColumn.FieldName == "ID" && gridView.FocusedRowHandle % 2 == 0;
};
|
VB |
AddHandler gridView.ShownEditor, Sub(s, e)
Dim view As GridView = TryCast(s, GridView)
view.ActiveEditor.Properties.ReadOnly = gridView.FocusedColumn.FieldName = "ID" AndAlso gridView.FocusedRowHandle Mod 2 = 0
End Sub
|
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 Cell Values
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.

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

C# |
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";
}
}
}
|
VB |
Private Sub GridView1_ValidatingEditor(ByVal sender As Object, ByVal e As DevExpress.XtraEditors.Controls.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
|
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
Validate Rows
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.

-
ColumnView.ValidateRow, ColumnView.InvalidRowException - similar 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.

C# |
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)));
if(val < 0) {
e.ErrorText = string.Format("{0}\r\n", Properties.Resources.SubTotalGreaterEqual);
e.Valid = false;
}
}
|
VB |
Imports Microsoft.VisualBasic
Private Sub gridView1_ValidateRow(ByVal sender As Object, ByVal e As DevExpress.XtraGrid.Views.Base.ValidateRowEventArgs)
Dim view As GridView = TryCast(sender, GridView)
Dim val As Single = Convert.ToSingle(view.GetRowCellValue(e.RowHandle, gridColumn3)) * Convert.ToInt16(view.GetRowCellValue(e.RowHandle, gridColumn4)) * (1 - Convert.ToSingle(view.GetRowCellValue(e.RowHandle, gridColumn5)))
If val < 0 Then
e.ErrorText = String.Format("{0}" & ControlChars.CrLf, My.Resources.SubTotalGreaterEqual)
e.Valid = False
End If
End Sub
|
Demos: Data Validation | Validate row data on losing focus

See Also
Is this topic helpful?
Additional Feedback
Close
|