windowsforms-753-controls-and-libraries-data-grid-data-editing-and-validation-modify-and-validate-cell-values.md
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
|
| |
A cell of a focused row
|
ColumnView.GetFocusedRowCellValue
ColumnView.GetFocusedRowCellDisplayText
|
ColumnView.SetFocusedRowCellValue
| |
Any row cell
|
ColumnView.GetRowCellValue
ColumnView.GetRowCellDisplayText
|
| |
A cell value in an underlying data source
|
ColumnView.GetListSourceRowCellValue
| | |
The currently edited cell
|
|
|
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).
string cellValue;
cellValue = gridView1.GetRowCellValue(2, "ID").ToString();
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.
string cellValue = gridView1.GetFocusedDisplayText();
Dim cellValue As String = GridView1.GetFocusedDisplayText()
Example 3 - Change the focused cell value
This example changes the value of the focused cell.
gridView1.SetRowCellValue(gridView1.FocusedRowHandle, gridView1.FocusedColumn, "New Value");
//or
gridView1.SetFocusedValue("New Value");
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.
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;
}
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.
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);
}
};
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
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.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.
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;
}
}
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
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:
if(gridView1.ActiveEditor != null) {
gridView1.ActiveEditor.EditValue = null;
}
If gridView1.ActiveEditor IsNot Nothing Then
gridView1.ActiveEditor.EditValue = Nothing
End If
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 Type | Default Editor and Repository Item |
|---|---|
| String, Numeric, TimeOnly | TextEdit, RepositoryItemTextEdit |
| Boolean | CheckEdit, RepositoryItemCheckEdit |
| Date-Time, DateOnly | DateEdit, RepositoryItemDateEdit |
| DateTimeOffset | DateTimeOffsetEdit, RepositoryItemDateTimeOffsetEdit |
| TimeSpan | TimeSpanEdit, RepositoryItemTimeSpanEdit |
| Enumeration | ComboBoxEdit, RepositoryItemComboBox |
| Picture/Image | PictureEdit, RepositoryItemPictureEdit |
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 a repository item, add it to the Grid’s RepositoryItems collection, and assign the repository item to the GridColumn.ColumnEdit property.
// Creates a 'ToggleSwitch' repository item.
RepositoryItemToggleSwitch edit = new RepositoryItemToggleSwitch();
// Adds the repository item to the grid's RepositoryItems collection.
gridControl.RepositoryItems.Add(edit);
// Assigns the repository item to the 'Mark' column.
gridView.Columns["Mark"].ColumnEdit = edit;
' 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.
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;
}
}
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.
// 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;
}
};
' 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.
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;
}
};
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
Handle the GridView.CustomRowCellEdit event to specify a specific in-place editor for a certain cell or a group of cells.
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraEditors.Repository;
public Form1() {
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;
};
}
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
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
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.
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;
};
}
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
|
Description
| | --- | --- | |
|
Invokes the focused cell’s editor.
| |
|
Closes the active editor and discards the changes made.
| |
|
Saves any changes made and closes the active editor.
| |
|
Saves any changes made without closing the active editor.
| |
|
Gets the active editor.
| |
|
Fires when the grid activates an in-place editor.
The following example specifies the current date and open the DateEdit‘s dropdown when the user starts to edit a value in the OrderDate column.
using DevExpress.XtraEditors;
using DevExpress.XtraGrid.Views.Grid;
private void GridView1_ShownEditor(object sender, EventArgs e) {
GridView view = sender as GridView;
if (view.FocusedColumn == colOrderDate) {
// Specifies the current date.
view.EditingValue = DateTime.Today;
// Gets the active editor.
DateEdit editor = view.ActiveEditor as DateEdit;
// Invokes the dropdown.
editor.ShowPopup();
}
}
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
| |
|
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.
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();
}
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:
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;
}
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 a View’s OptionsBehavior.Editable option to disable all cells in the View.
gridView1.OptionsBehavior.Editable = false;
gridView1.OptionsBehavior.Editable = False
Disable a column’s OptionsColumn.AllowEdit to disable its cells.
gridView1.OptionsBehavior.Editable = true;
// Disables cells displayed in the PropertyA column.
gridView1.Columns["PropertyA"].OptionsColumn.AllowEdit = false;
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.
gridView1.OptionsBehavior.Editable = true;
gridView1.Columns["PropertyA"].OptionsColumn.AllowEdit = true;
// Makes cells in the PropertyA column read-only.
gridView1.Columns["PropertyA"].OptionsColumn.ReadOnly = true;
gridView1.OptionsBehavior.Editable = True
gridView1.Columns["PropertyA"].OptionsColumn.AllowEdit = True
' Makes cells in the PropertyA column read-only.
gridView1.Columns["PropertyA"].OptionsColumn.ReadOnly = True
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
Use one of the following techniques to disable fields in the Edit Form:
e.BindableControls property to access the required editor and disable its Editable property.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:
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.
|
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.
| |
|
Fires before the Edit Form is displayed. Handle this event to hide the Edit Form and prevent a user from editing values in certain cells.
The following example prevents a user from editing cell values in even rows:
gridView.OptionsBehavior.EditingMode = GridEditingMode.EditForm;
gridView1.EditFormShowing += (s, e) => {
e.Allow = e.RowHandle % 2 != 0;
};
gridView.OptionsBehavior.EditingMode = GridEditingMode.EditForm
AddHandler gridView1.EditFormShowing, Sub(s, e) e.Allow = e.RowHandle Mod 2 <> 0
|
Important
The Edit Form uses the Tag property of repository items internally. Do not set the Tag property to avoid runtime issues.
The Edit Form is a container control with data editors (fields). Data editors are bound to corresponding fields/properties in a data record. Do one of the following to specify values of these data editors:
The following example handles the EditFormPrepared event to focus the ‘first’ Date Editor when a user opens the Edit Form.
using DevExpress.XtraGrid.Views.Grid;
// ...
gridView.OptionsBehavior.EditingMode = GridEditingMode.EditForm;
DateEdit dateEdit = null;
gridView.EditFormPrepared += (s, e) => {
// The 'e.BindableControls' collection contains the editors in the Edit Form.
foreach (Control item in e.BindableControls) {
dateEdit = item as DateEdit;
if (dateEdit != null) {
// Focuses the Date Editor.
dateEdit.Select();
return;
}
}
};
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.
The Grid control creates the Edit Form according to the following rules:
Tip
Invoke the Data Grid Designer and switch to the EditForm Designer page to customize the layout of the Edit Form.
|
API
|
Description
| | --- | --- | |
|
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.
|
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();
}
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
Tip
How to implement CRUD operations in read-only data sources (WinForms Data Grid)
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.
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;
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
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:
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.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).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.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.
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";
}
}
}
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.
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;
};
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:
Use the editor’s InplaceModeImmediatePostChanges property to control this behavior. The WindowsFormsSettings.InplaceEditorUpdateMode property allows you to control update behavior globally.
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
Use the DXErrorProvider component and implement the IDXDataErrorInfo interface in a business object to automatically indicate invalid values and display text-based feedback (tooltips).
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" }
};
}
}
}
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:
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;
}
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
The Data Grid and other DevExpress data-aware controls (Gantt Control, Vertical Grid, TreeList, etc.) do not interact with real data storages. Instead, they use data sources connected to these storages.
Data-aware controls save user edits to data sources. You should post these changes to underlying storages. Handle the ColumnView.RowUpdated event to post modified row values to the data storage. The Grid raises this event when a user moves focus to another row.
void gridView1_RowUpdated(object sender, RowObjectEventArgs e) {
// Use data source API to save changes.
}
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.
void gridView1_CellValueChanged(object sender, CellValueChangedEventArgs e) {
ColumnView view = sender as ColumnView;
view.CloseEditor();
if(view.UpdateCurrentRow()) {
// Use data source API to save changes.
}
}
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:
repositoryItemCheckedComboBoxEdit1.EditValueChanged += (s, e) => {
gridControl1.FocusedView.PostEditor();
};
AddHandler repositoryItemCheckedComboBoxEdit1.EditValueChanged, Sub(s, e)
gridControl1.FocusedView.PostEditor()
End Sub
This example assigns a RepositoryItemButtonEdit to a grid column and customizes related settings.
This example handles the GridView.CustomRowCellEdit event to display cell values in the first button of a Button Editor used to edit column values.
This example uses two ways to display colored progress bars in cells:
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.
The example implements two ways to address this task:
This example creates an empty repository item and handles the CustomRowCellEdit event to assign the repository item to grid cells based on a condition.
This example applies a new value to all selected cells.
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.
See Also