windowsforms-752-controls-and-libraries-data-grid-data-editing-and-validation-add-and-remove-rows.md
The Data Grid uses methods of the data source assigned to the GridControl.DataSource property to add and remove rows. The data source must be editable (not read-only). A data source that implements the IBindingList interface must have AllowNew and AllowRemove settings enabled.
Note
The Data Grid does not support lists with simple type objects (for example, List<string>). If you create a list of classes with a property of the required simple type with an empty default constructor, the Data Grid can delete existing rows but cannot add new rows.
The New Item Row allows users to add new rows. Use the GridOptionsView.NewItemRowPosition property to display the New Item Row in a Data Grid:
using DevExpress.XtraGrid.Views.Grid;
gridView1.OptionsView.NewItemRowPosition = NewItemRowPosition.Top;
Imports DevExpress.XtraGrid.Views.Grid
gridView1.OptionsView.NewItemRowPosition = NewItemRowPosition.Top
When a user starts editing within the New Item Row, the Data Grid initializes a new row object and raises the ColumnView.InitNewRow event, which allows you to initialize the new row with default values.
The Data Grid adds a new row object to the data source in the following cases:
Run Demo: Table View Run Demo: Use New Item Row to Add Rows
Tip
Use the GridControl.NewItemRowHandle constant to obtain the New Item Row ‘s handle.
The AddNewRow() method creates a new (blank) row in the View and raises the InitNewRow event, which allows you to initialize the new row with default values.
Note
The data source must support the IBindingList interface.
gridView1.AddNewRow();
gridView1.AddNewRow()
If the View displays the New Item Row, the AddNewRow method moves focus to the New Item Row. Otherwise, the new row is temporarily displayed below existing data rows.
Handle the InitNewRow event to initialize cells in the New Item Row with default values. Use the SetRowCellValue method to specify cell values.
The View raises the ColumnView.InitNewRow event in the following cases:
The following example adds a new row, initializes the new row with default values, and saves the new row to the grid’s data source:
public Form1() {
InitializeComponent();
gridControl1.DataSource = new BindingList<DataItem>() {
new DataItem() { ValueA = "Value A10", ValueB = 10 },
new DataItem() { ValueA = "Value A11", ValueB = 11 },
};
gridView1.InitNewRow += GridView1_InitNewRow;
}
// Initialize a new row with default values.
void GridView1_InitNewRow(object sender, DevExpress.XtraGrid.Views.Grid.InitNewRowEventArgs e) {
gridView1.SetRowCellValue(e.RowHandle, "ValueA", "Default Value");
gridView1.SetRowCellValue(e.RowHandle, "ValueB", 1);
}
void buttonAddRow_Click(object sender, EventArgs e) {
// Add a new row.
gridView1.AddNewRow();
// Save the new row to the grid's data source.
gridView1.UpdateCurrentRow();
}
public class DataItem {
public string ValueA { get; set; }
public int ValueB { get; set; }
}
Public Sub New()
InitializeComponent()
gridControl1.DataSource = New BindingList(Of DataItem)() From {
New DataItem() With {
.ValueA = "Value A10",
.ValueB = 10
},
New DataItem() With {
.ValueA = "Value A11",
.ValueB = 11
}
}
AddHandler gridView1.InitNewRow, AddressOf GridView1_InitNewRow
End Sub
' Initialize a new row with default values.
Private Sub GridView1_InitNewRow(ByVal sender As Object, ByVal e As DevExpress.XtraGrid.Views.Grid.InitNewRowEventArgs)
gridView1.SetRowCellValue(e.RowHandle, "ValueA", "Default Value")
gridView1.SetRowCellValue(e.RowHandle, "ValueB", 1)
End Sub
Private Sub buttonAddRow_Click(ByVal sender As Object, ByVal e As EventArgs)
' Add a new row.
gridView1.AddNewRow()
' Save the new row to the grid's data source.
gridView1.UpdateCurrentRow()
End Sub
Public Class DataItem
Public Property ValueA As String
Public Property ValueB As Integer
End Class
Tip
Read the following help topic for additional information: Get and Modify Cell Values in Code.
Handle the ColumnView.ValidateRow event to validate cell values in the new row before the row is added to the grid’s data source.
The following example adds a new row to the focused data group. Data within the Grid View must be grouped against one or more columns.
//...
gridView1.OptionsNavigation.AutoFocusNewRow = true;
//...
void AddNewRowToFocusedGroup(DevExpress.XtraGrid.Views.Grid.GridView View) {
// Get the handle of the first data row in the focused group
// The row supplies group column values for the new row
int rowHandle = View.GetDataRowHandleByGroupRowHandle(View.FocusedRowHandle);
// Get the number of group columns
int groupColumnCount = View.GroupedColumns.Count;
// Add a new row
View.AddNewRow();
// Set cell values corresponding to group columns
for (int i = 0; i < groupColumnCount; i++) {
View.SetRowCellValue(GridControl.NewItemRowHandle, View.GroupedColumns[i],
View.GetRowCellValue(rowHandle, View.GroupedColumns[i]));
}
// Add the new row to the data source
// The row moves to its final position within the group
View.UpdateCurrentRow();
}
Private Sub AddNewRowInGroupMode(ByVal View As DevExpress.XtraGrid.Views.Grid.GridView)
'...
gridView1.OptionsNavigation.AutoFocusNewRow = True
'...
' Get the handle of the first data row in the focused group
' The row supplies group column values for the new row
Dim rowHandle As Integer = View.GetDataRowHandleByGroupRowHandle(View.FocusedRowHandle)
' Get the number of group columns
Dim groupColumnCount As Integer = View.GroupedColumns.Count
' Add a new row
View.AddNewRow()
' Set cell values corresponding to group columns
For i As Integer = 0 To groupColumnCount - 1
View.SetRowCellValue(GridControl.NewItemRowHandle, View.GroupedColum(i),
View.GetRowCellValue(rowHandle, View.GroupedColumns(i)))
Next i
' Add the new row to the data source
' The row moves to its final position within the group
View.UpdateCurrentRow()
End Sub
This example adds a new row when a user finishes editing the last data cell.
The code below adds a new (blank) record to the BindingList<T> that serves as a data source for a Data Grid:
void barButtonItem1_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e) {
(gridControl1.DataSource as BindingList<SalesPerson>).AddNew();
}
Private Sub barButtonItem1_ItemClick(ByVal sender As Object, ByVal e As DevExpress.XtraBars.ItemClickEventArgs)
TryCast(gridControl1.DataSource, BindingList(Of SalesPerson)).AddNew()
End Sub
You can use data source API to add/remove rows if the data source implements such API.
If the data source does not implement the IBindingList interface, it does not send add/remove notifications to the Data Grid. In this case, use one of the following methods to update/refresh the Data Grid:
Tip
Enable the GridOptionsNavigation.AutoFocusNewRow option to automatically focus the new row. This option is in effect if the data source sends add/remove notifications to the Data Grid.
Use the DeleteRow(Int32) method to delete the specified data row. The data source must allow delete operations.
Note
DeleteRow method deletes the master row together with its child rows.DeleteRow method deletes a group row and all data rows in the group.A DeleteRow(Int32) method call triggers the ColumnView.RowDeleting event. A successful delete operation raises the ColumnView.RowDeleted event.
The following code deletes the focused row when a user presses the Ctrl+Del keyboard shortcut:
private void gridView1_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e) {
if (e.KeyCode == Keys.Delete && e.Modifiers == Keys.Control) {
if (MessageBox.Show("Delete row?", "Confirmation", MessageBoxButtons.YesNo) !=
DialogResult.Yes)
return;
GridView view = sender as GridView;
view.DeleteRow(view.FocusedRowHandle);
}
}
Private Sub GridView1_KeyDown(ByVal sender As Object, _
ByVal e As System.Windows.Forms.KeyEventArgs) Handles GridView1.KeyDown
If (e.KeyCode = Keys.Delete And e.Modifiers = Keys.Control) Then
If (MessageBox.Show("Delete row?", "Confirmation", _
MessageBoxButtons.YesNo) <> DialogResult.Yes) Then Return
Dim view As GridView = CType(sender, GridView)
view.DeleteRow(view.FocusedRowHandle)
End If
End Sub
Use the DeleteSelectedRows() method to delete selected rows (or rows with selected cells if multiple cell selection mode is enabled).
A DeleteSelectedRows() method call triggers the ColumnView.RowDeleting event for each row to be deleted. Every successful delete operation raises the ColumnView.RowDeleted event.
Run Demo: Remove Rows with Ctrl+Delete Run Demo: Prevent a Row From Being Deleted
Tip
Read the following help topic for additional information: Multiple Row and Cell Selection.
The Data Grid integrates the Data Navigator that allows users to navigate and edit data. Enable the GridControl.UseEmbeddedNavigator option to display the Data Navigator.
View Example: Embedded Data Navigator: Create a Custom Button
You can also use a standalone ControlNavigator. Use the ControlNavigator.NavigatableControl property to bind the Control Navigator to a Data Grid:
ControlNavigator navigator = new ControlNavigator();
navigator.Location = new Point(0, 0);
navigator.NavigatableControl = gridControl1;
this.Controls.Add(navigator);
Dim navigator As New ControlNavigator()
navigator.Location = New Point(0, 0)
navigator.NavigatableControl = gridControl1
Me.Controls.Add(navigator)
The Data Grid, like other DevExpress data-aware controls (for example, Gantt Control, Vertical Grid, TreeList), does not interact with the database directly. The Data Grid operates with a data source connected to the database. The Data Grid saves user edits to the data source, but you need to manually post these changes to the database.
Handle the ColumnView.RowUpdated event to post modified row values to the database. The event fires in the following cases:
Tip
Read the following help topic for additional information: Post Data to an Underlying Data Source.
The following code handles the RowUpdated event and calls the table adapter’s Update method to post changes to the database:
void gridView1_RowUpdated(object sender, RowObjectEventArgs e) {
categoriesTableAdapter.Adapter.Update(nwindDataSet);
}
Sub gridView1_RowUpdated(ByVal sender As Object, ByVal e As RowObjectEventArgs)
categoriesTableAdapter.Adapter.Update(nwindDataSet)
End Sub
Note
The RowUpdated event does not fire while an editor is active (the View.IsEditing property returns true ). To trigger this event manually, call the BaseView.CloseEditor method. The CloseEditor method saves changes, closes the editor, and calls the View’s UpdateCurrentRow() method.
Tip
Read the following help topics for additional information about row validation:
This example displays custom rows (ordinal, blank/group, and summary) in the Data Grid. Custom rows do not exist in the grid’s data source. Custom rows support data editing, sorting, and grouping.
The example creates a data source wrapper and handles the following events:
DevExpress WinForms UI controls introduce similar API to add, remove, and initialize rows. Read the following quick-reference guides for detailed information: