Back to Devexpress

Add and Remove Rows

wpf-6123-controls-and-libraries-data-grid-data-editing-and-validation-add-and-remove-rows.md

latest15.3 KB
Original Source

Add and Remove Rows

  • Jul 27, 2025
  • 6 minutes to read

New Item Row

The New Item Row is an empty row at the top or the bottom of the View. Users can enter data into this row to create new rows.

To show the New Item Row , set the TableView.NewItemRowPosition / TreeListView.NewItemRowPosition property to Top or Bottom.

TableView : NewItemRowPosition = Top

TableView : NewItemRowPosition = Bottom

TreeListView : NewItemRowPosition = Top

TreeListView : NewItemRowPosition = Bottom

Run Demo: New Item Row in TableView Run Demo: New Item Row in TreeListView

A user should enter values in the New Item Row. The GridControl checks whether values are valid and displays the row at the position according to the current filter, group, and sort settings:

The GridControl validates the New Item Row ‘s cells in the same way as other data cells. Refer to Input Validation for more information.

In TreeListView, a new row is added to the root level. Users can drag this row anywhere in the hierarchy. Set the DataViewBase.AllowDragDrop property to true to allow drag-and-drop operations.

Users can press Esc while the row is focused to cancel appending a new row.

If a cell is in edit mode, a user should press the Esc key twice to close an editor and cancel appending.

You can customize the New Item Row that has the NewItemRowPosition.Top position. Use the ColumnBase.NewItemRowCellStyle / TableView.NewItemRowCellStyle / TreeListView.NewItemRowCellStyle property to specify a style for the column cell(s) within the New Item Row.

Note

The GridControl adds new rows only if source objects have a public parameterless constructor. In other cases, you should handle the GridViewBase.AddingNewRow / TreeListView.AddingNewNode event to create new rows.

Initialize New Item Row

You can initialize the New Item Row with default values:

The GridViewBase.AddingNewRow and TreeListView.AddingNewNode events allow you to specify a new data record. These events occur before the GridControl adds a new record to your data source.

When you handle these events, you can also initialize default properties of the created data record.

xaml
<dxg:GridControl>
    <dxg:GridControl.View>
        <dxg:TableView NewItemRowPosition="Top" 
                       AddingNewRow="view_AddingNewRow" />
    </dxg:GridControl.View>
</dxg:GridControl>
csharp
void view_AddingNewRow(object sender, System.ComponentModel.AddingNewEventArgs e) {
    e.NewObject = new Product(selectedCompany) {
        ProductName = "", 
        CompanyName = "New Company", 
        UnitPrice = 10, 
        Discontinued = false 
    };
}
vb
Private Sub view_AddingNewRow(ByVal sender As Object, ByVal e As System.ComponentModel.AddingNewEventArgs)
    e.NewObject = New Product(selectedCompany) With {
        .ProductName = "",
        .CompanyName = "New Company",
        .UnitPrice = 10,
        .Discontinued = False
    }
End Sub

View Example: How to Initialize the New Item Row with Default Values

You can also use the GridViewBase.AddingNewRowCommand and TreeListView.AddingNewNodeCommand properties to maintain a clean MVVM pattern. These properties allow you to specify a new data record in a ViewModel.

If the TreeListView is in Self-Referential mode, you cannot add a new node with the duplicated primary key. Handle the TreeListView.AddingNewNode event and initialize a field specified in the TreeListView.KeyFieldName property with a unique primary key.

xaml
<dxg:GridControl>
    <dxg:GridControl.View>
        <dxg:TreeListView x:Name="view"
                          KeyFieldName="ID" 
                          ParentFieldName="ParentID"
                          NewItemRowPosition="Top"
                          AddingNewNode="view_AddingNewNode"/>
    </dxg:GridControl.View>
</dxg:GridControl>
csharp
void view_AddingNewNode(object sender, DevExpress.Xpf.Grid.TreeList.TreeListAddingNewEventArgs e) {
    e.NewObject = new Employee() {
        ID = view.TotalNodesCount + 1,
        Name = "",
        Department = "Finance",
        Position = "Manager"
    };
}
vb
Private Sub view_AddingNewNode(ByVal sender As Object, ByVal e As DevExpress.Xpf.Grid.TreeList.TreeListAddingNewEventArgs)
    e.NewObject = New Employee() With {
        .ID = view.TotalNodesCount + 1,
        .Name = "",
        .Department = "Finance",
        .Position = "Manager"
    }
End Sub

Data Navigator

The embedded Data Navigator allows users to add and remove rows.

To show the Data Navigator, set the TableView.ShowDataNavigator / TreeListView.ShowDataNavigator property to true.

To add a new row, a user should click the Data Navigator‘s Append (+) button. To remove a row, a user should focus the row and click the Data Navigator‘s Delete (-) button.

You can initialize a new row with default values. Refer to the Initialize New Item Row section for more information.

Use the DataViewBase.DataNavigatorButtons property to specify which buttons to display in the Data Navigator.

Delete Key

Specify the DataControlBase.DeleteKeyBehavior property to define the action executed when a user presses the Delete key:

Add and Remove Rows in Code

Add Rows

Call the TableView.AddNewRow / TreeListView.AddNewNode method to add a new row. If the New Item Row is enabled, these methods move focus to this element. Otherwise, they temporarily add an empty row at the bottom.

Commands : TableViewCommands.AddNewRow / TreeListViewCommands.AddNewNode

xaml
<dxg:GridControl x:Name="grid" AutoGenerateColumns="AddNew" ItemsSource="{Binding PersonList}">
    <dxg:GridControl.View>
        <dxg:TableView x:Name="view"/>
    </dxg:GridControl.View>
</dxg:GridControl>
<!-- -->
<Button Click="addNewRow">Add a New Row</Button>
csharp
void addNewRow(object sender, RoutedEventArgs e) {
    view.AddNewRow();
}
vb
Private Sub addNewRow(ByVal sender As Object, ByVal e As RoutedEventArgs)
    view.AddNewRow()
End Sub

Use DataControlBase.NewItemRowHandle to get the new row and set its values.

Topic : Obtain and Set Cell Values

csharp
void addNewRow(object sender, RoutedEventArgs e) {
    view.AddNewRow();
    int newRowHandle = DataControlBase.NewItemRowHandle;
    grid.SetCellValue(newRowHandle, "ProductName", "New Product");
    grid.SetCellValue(newRowHandle, "CompanyName", "New Company");
    grid.SetCellValue(newRowHandle, "UnitPrice", 10);            
    grid.SetCellValue(newRowHandle, "Discontinued", false);
}
vb
Private Sub addNewRow(ByVal sender As Object, ByVal e As RoutedEventArgs)
    view.AddNewRow()
    Dim newRowHandle As Integer = DataControlBase.NewItemRowHandle
    grid.SetCellValue(newRowHandle, "ProductName", "New Product")
    grid.SetCellValue(newRowHandle, "CompanyName", "New Company")
    grid.SetCellValue(newRowHandle, "UnitPrice", 10)
    grid.SetCellValue(newRowHandle, "Discontinued", False)
End Sub

After values are set and accepted, the new row moves according to the current filter, group, and sort settings.

View Example: How to Add and Remove Rows in Code

After a user posts the new row to the control, the Data Grid raises the ValidateRow event and executes the ValidateRowCommand. Use them to validate values, check database constraints, and insert the row to the database.

xaml
<dxg:GridControl ItemsSource="{Binding ItemsSource}">
    <dxg:GridControl.View>
        <dxg:TableView NewItemRowPosition="Top"
                       ValidateRowCommand="{Binding ValidateRowCommand}" />
</dxg:GridControl>
csharp
[DevExpress.Mvvm.DataAnnotations.Command]
public void ValidateRow(DevExpress.Mvvm.Xpf.RowValidationArgs args) {
    var item = (EntityFrameworkIssues.Issues.User)args.Item;
    if(args.IsNewItem)
        _Context.Users.Add(item);
    _Context.SaveChanges();
}
vb
<DevExpress.Mvvm.DataAnnotations.Command>
Public Sub ValidateRow(ByVal args As DevExpress.Mvvm.Xpf.RowValidationArgs)
    Dim item = CType(args.Item, EntityFrameworkIssues.Issues.User)
    If args.IsNewItem Then _Context.Users.Add(item)
    _Context.SaveChanges()
End Sub

Remove Rows

Call the GridViewBase.DeleteRow / TreeListView.DeleteNode method to delete the specified row. The row is identified by its handle – a non-negative integer value.

Commands : DeleteFocusedRow and DeleteSelectedRows

xaml
<dxg:GridControl x:Name="grid" AutoGenerateColumns="AddNew" ItemsSource="{Binding PersonList}">
    <dxg:GridControl.View>
        <dxg:TableView x:Name="view"/>
    </dxg:GridControl.View>
</dxg:GridControl>
<!-- -->
<Button Click="deleteRow">Delete the Focused Row</Button>
csharp
void deleteRow(object sender, RoutedEventArgs e) {
    view.DeleteRow(view.FocusedRowHandle);
}
vb
Private Sub deleteRow(ByVal sender As Object, ByVal e As RoutedEventArgs)
    view.DeleteRow(view.FocusedRowHandle)
End Sub

View Example: How to Add and Remove Rows in Code

After a delete operation is executed, the Data Grid raises the ValidateRowDeletion / ValidateNodeDeletion events and calls the ValidateRowDeletionCommand / ValidateNodeDeletionCommand. Use them to validate rows, check database constraints, and delete rows from the database.

csharp
[DevExpress.Mvvm.DataAnnotations.Command]
public void ValidateDeleteRows(DevExpress.Mvvm.Xpf.DeleteRowsValidationArgs args) {
    var item = (EFCoreIssues.Issues.User)args.Items.Single();
    _Context.Users.Remove(item);
    _Context.SaveChanges();
}
vb
<DevExpress.Mvvm.DataAnnotations.Command>
Public Sub ValidateDeleteRows(ByVal args As DevExpress.Mvvm.Xpf.DeleteRowsValidationArgs)
    Dim item = CType(args.Items.Single(), EFCoreIssues.Issues.User)
    _Context.Users.Remove(item)
    _Context.SaveChanges()
End Sub

See Also

Obtain and Set Cell Values in Code

Input Validation

How to Initialize a New Row when the Editor is Shown