# Add and Remove Rows | WPF Controls | DevExpress Documentation

## New Item Row

The **New Item Row** is an empty row at the top or the bottom of the [View](/WPF/6293/controls-and-libraries/data-grid/views). Users can enter data into this row to create new rows.

To show the **New Item Row**, set the [TableView.NewItemRowPosition](/WPF/DevExpress.Xpf.Grid.TableView.NewItemRowPosition) / [TreeListView.NewItemRowPosition](/WPF/DevExpress.Xpf.Grid.TreeListView.NewItemRowPosition) property to **Top** or **Bottom**. 

![**TableView**: NewItemRowPosition = Top](/WPF/images/new-item-row-table-view-top.png)**TableView**: NewItemRowPosition = Top

![**TableView**: NewItemRowPosition = Bottom](/WPF/images/new-item-row-table-view-bottom.png)**TableView**: NewItemRowPosition = Bottom

![**TreeListView**: NewItemRowPosition = Top](/WPF/images/new-item-row-tree-list-view-top.png)**TreeListView**: NewItemRowPosition = Top

![**TreeListView**: NewItemRowPosition = Bottom](/WPF/images/new-item-row-tree-list-view-bottom.png)**TreeListView**: NewItemRowPosition = Bottom

[Run Demo: New Item Row in TableView](dxdemo://Wpf/DXGrid/MainDemo/NewItemRow) [Run Demo: New Item Row in TreeListView](dxdemo://Wpf/DXTreeList/MainDemo/NewItemRow)

A user should enter values in the **New Item Row**. The [GridControl](/WPF/DevExpress.Xpf.Grid.GridControl) checks whether values are valid and displays the row at the position according to the current filter, group, and sort settings:

![](/WPF/images/new-tem-row-table-view.gif)

The [GridControl](/WPF/DevExpress.Xpf.Grid.GridControl) validates the **New Item Row**‘s cells in the same way as other data cells. Refer to [Input Validation](/WPF/7358/controls-and-libraries/data-grid/data-editing-and-validation/input-validation) for more information.

In [TreeListView](/WPF/DevExpress.Xpf.Grid.TreeListView), a new row is added to the root level. Users can drag this row anywhere in the hierarchy. Set the [DataViewBase.AllowDragDrop](/WPF/DevExpress.Xpf.Grid.DataViewBase.AllowDragDrop) property to **true** to allow drag-and-drop operations. 

![](/WPF/images/new-tem-row-tree-list-view-drag.gif)

Users can press <kbd>Esc</kbd> while the row is focused to cancel appending a new row. 

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

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

Note

The [GridControl](/WPF/DevExpress.Xpf.Grid.GridControl) adds new rows only if source objects have a public parameterless constructor. In other cases, you should handle the [GridViewBase.AddingNewRow](/WPF/DevExpress.Xpf.Grid.GridViewBase.AddingNewRow) / [TreeListView.AddingNewNode](/WPF/DevExpress.Xpf.Grid.TreeListView.AddingNewNode) event to create new rows.

### Initialize New Item Row

You can initialize the **New Item Row** with default values:

![DevExpress WPF | Grid Control - Initialize New Item Row](/WPF/images/initialize-new-item-row.gif)

The [GridViewBase.AddingNewRow](/WPF/DevExpress.Xpf.Grid.GridViewBase.AddingNewRow) and [TreeListView.AddingNewNode](/WPF/DevExpress.Xpf.Grid.TreeListView.AddingNewNode) events allow you to specify a new data record. These events occur before the [GridControl](/WPF/DevExpress.Xpf.Grid.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

<section id="tabpanel_GEA6F8q-l+_tabid-xaml" role="tabpanel" data-tab="tabid-xaml">
<pre><code class="lang-xaml">&lt;dxg:GridControl&gt;
    &lt;dxg:GridControl.View&gt;
        &lt;dxg:TableView NewItemRowPosition=&quot;Top&quot; 
                       AddingNewRow=&quot;view_AddingNewRow&quot; /&gt;
    &lt;/dxg:GridControl.View&gt;
&lt;/dxg:GridControl&gt;
</code></pre></section>

- C#
- VB.NET

<section id="tabpanel_GEA6F8q-l+-1_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code class="lang-csharp">void view_AddingNewRow(object sender, System.ComponentModel.AddingNewEventArgs e) {
    e.NewObject = new Product(selectedCompany) {
        ProductName = &quot;&quot;, 
        CompanyName = &quot;New Company&quot;, 
        UnitPrice = 10, 
        Discontinued = false 
    };
}
</code></pre></section>
<section id="tabpanel_GEA6F8q-l+-1_tabid-vb" role="tabpanel" data-tab="tabid-vb" aria-hidden="true" hidden="hidden">
<pre><code class="lang-vb">Private Sub view_AddingNewRow(ByVal sender As Object, ByVal e As System.ComponentModel.AddingNewEventArgs)
    e.NewObject = New Product(selectedCompany) With {
        .ProductName = &quot;&quot;,
        .CompanyName = &quot;New Company&quot;,
        .UnitPrice = 10,
        .Discontinued = False
    }
End Sub
</code></pre></section>

[View Example: How to Initialize the New Item Row with Default Values](https://github.com/DevExpress-Examples/wpf-data-grid-initialize-new-item-row-with-default-values)

You can also use the [GridViewBase.AddingNewRowCommand](/WPF/DevExpress.Xpf.Grid.GridViewBase.AddingNewRowCommand) and [TreeListView.AddingNewNodeCommand](/WPF/DevExpress.Xpf.Grid.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](/WPF/DevExpress.Xpf.Grid.TreeListView) is in [Self-Referential](/WPF/9571/controls-and-libraries/data-grid/display-hierarchical-data/bind-to-self-referential-data-structure) mode, you cannot add a new node with the duplicated primary key. Handle the [TreeListView.AddingNewNode](/WPF/DevExpress.Xpf.Grid.TreeListView.AddingNewNode) event and initialize a field specified in the [TreeListView.KeyFieldName](/WPF/DevExpress.Xpf.Grid.TreeListView.KeyFieldName) property with a unique primary key.

- XAML

<section id="tabpanel_GEA6F8q-l+-2_tabid-xaml" role="tabpanel" data-tab="tabid-xaml">
<pre><code class="lang-xaml">&lt;dxg:GridControl&gt;
    &lt;dxg:GridControl.View&gt;
        &lt;dxg:TreeListView x:Name=&quot;view&quot;
                          KeyFieldName=&quot;ID&quot; 
                          ParentFieldName=&quot;ParentID&quot;
                          NewItemRowPosition=&quot;Top&quot;
                          AddingNewNode=&quot;view_AddingNewNode&quot;/&gt;
    &lt;/dxg:GridControl.View&gt;
&lt;/dxg:GridControl&gt;
</code></pre></section>

- C#
- VB.NET

<section id="tabpanel_GEA6F8q-l+-3_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code class="lang-csharp">void view_AddingNewNode(object sender, DevExpress.Xpf.Grid.TreeList.TreeListAddingNewEventArgs e) {
    e.NewObject = new Employee() {
        ID = view.TotalNodesCount + 1,
        Name = &quot;&quot;,
        Department = &quot;Finance&quot;,
        Position = &quot;Manager&quot;
    };
}
</code></pre></section>
<section id="tabpanel_GEA6F8q-l+-3_tabid-vb" role="tabpanel" data-tab="tabid-vb" aria-hidden="true" hidden="hidden">
<pre><code class="lang-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 = &quot;&quot;,
        .Department = &quot;Finance&quot;,
        .Position = &quot;Manager&quot;
    }
End Sub
</code></pre></section>

## Data Navigator

The embedded [Data Navigator](/WPF/114118/controls-and-libraries/data-grid/visual-elements/common-elements/data-navigator) allows users to add and remove rows.

To show the [Data Navigator](/WPF/114118/controls-and-libraries/data-grid/visual-elements/common-elements/data-navigator), set the [TableView.ShowDataNavigator](/WPF/DevExpress.Xpf.Grid.TableView.ShowDataNavigator) / [TreeListView.ShowDataNavigator](/WPF/DevExpress.Xpf.Grid.TreeListView.ShowDataNavigator) property to **true**.

![](/WPF/images/data-navigator.png)

To add a new row, a user should click the [Data Navigator](/WPF/114118/controls-and-libraries/data-grid/visual-elements/common-elements/data-navigator)‘s **Append (+)** button. To remove a row, a user should focus the row and click the [Data Navigator](/WPF/114118/controls-and-libraries/data-grid/visual-elements/common-elements/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](/WPF/DevExpress.Xpf.Grid.DataViewBase.DataNavigatorButtons) property to specify which buttons to display in the **Data Navigator**.

## Delete Key

Specify the [DataControlBase.DeleteKeyBehavior](/WPF/DevExpress.Xpf.Grid.DataControlBase.DeleteKeyBehavior) property to define the action executed when a user presses the Delete key:

- Delete the focused row (for [single selection mode](/WPF/6121/controls-and-libraries/data-grid/focus-navigation-selection/focus)).
- Delete selected rows (for [multiple selection mode](/WPF/7359/controls-and-libraries/data-grid/focus-navigation-selection/multiple-row-selection)).

## Add and Remove Rows in Code

### Add Rows

Call the [TableView.AddNewRow](/WPF/DevExpress.Xpf.Grid.TableView.AddNewRow%28System.Boolean%29) / [TreeListView.AddNewNode](/WPF/DevExpress.Xpf.Grid.TreeListView.AddNewNode.overloads) 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](/WPF/DevExpress.Xpf.Grid.TableViewCommands.AddNewRow) / [TreeListViewCommands.AddNewNode](/WPF/DevExpress.Xpf.Grid.TreeListViewCommands.AddNewNode)

- Xaml

<section id="tabpanel_GEA6F8q-l+-4_tabid-xaml" role="tabpanel" data-tab="tabid-xaml">
<pre><code class="lang-xaml">&lt;dxg:GridControl x:Name=&quot;grid&quot; AutoGenerateColumns=&quot;AddNew&quot; ItemsSource=&quot;{Binding PersonList}&quot;&gt;
    &lt;dxg:GridControl.View&gt;
        &lt;dxg:TableView x:Name=&quot;view&quot;/&gt;
    &lt;/dxg:GridControl.View&gt;
&lt;/dxg:GridControl&gt;
&lt;!-- --&gt;
&lt;Button Click=&quot;addNewRow&quot;&gt;Add a New Row&lt;/Button&gt; 
</code></pre></section>

- C#
- VB.NET

<section id="tabpanel_GEA6F8q-l+-5_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code class="lang-csharp">void addNewRow(object sender, RoutedEventArgs e) {
    view.AddNewRow();
}
</code></pre></section>
<section id="tabpanel_GEA6F8q-l+-5_tabid-vb" role="tabpanel" data-tab="tabid-vb" aria-hidden="true" hidden="hidden">
<pre><code class="lang-vb">Private Sub addNewRow(ByVal sender As Object, ByVal e As RoutedEventArgs)
    view.AddNewRow()
End Sub
</code></pre></section>

Use [DataControlBase.NewItemRowHandle](/WPF/DevExpress.Xpf.Grid.DataControlBase.NewItemRowHandle) to get the new row and set its values.

**Topic**: [Obtain and Set Cell Values](/WPF/6150/controls-and-libraries/data-grid/data-editing-and-validation/modify-cell-values/obtain-and-set-cell-values-in-code)

- C#
- VB.NET

<section id="tabpanel_GEA6F8q-l+-6_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code class="lang-csharp">void addNewRow(object sender, RoutedEventArgs e) {
    view.AddNewRow();
    int newRowHandle = DataControlBase.NewItemRowHandle;
    grid.SetCellValue(newRowHandle, &quot;ProductName&quot;, &quot;New Product&quot;);
    grid.SetCellValue(newRowHandle, &quot;CompanyName&quot;, &quot;New Company&quot;);
    grid.SetCellValue(newRowHandle, &quot;UnitPrice&quot;, 10);            
    grid.SetCellValue(newRowHandle, &quot;Discontinued&quot;, false);
} 
</code></pre></section>
<section id="tabpanel_GEA6F8q-l+-6_tabid-vb" role="tabpanel" data-tab="tabid-vb" aria-hidden="true" hidden="hidden">
<pre><code class="lang-vb">Private Sub addNewRow(ByVal sender As Object, ByVal e As RoutedEventArgs)
    view.AddNewRow()
    Dim newRowHandle As Integer = DataControlBase.NewItemRowHandle
    grid.SetCellValue(newRowHandle, &quot;ProductName&quot;, &quot;New Product&quot;)
    grid.SetCellValue(newRowHandle, &quot;CompanyName&quot;, &quot;New Company&quot;)
    grid.SetCellValue(newRowHandle, &quot;UnitPrice&quot;, 10)
    grid.SetCellValue(newRowHandle, &quot;Discontinued&quot;, False)
End Sub
</code></pre></section>

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

![](/WPF/images/new-item-row-adding.png)

[View Example: How to Add and Remove Rows in Code](https://github.com/DevExpress-Examples/wpf-data-grid-add-and-remove-rows-in-code)

After a user posts the new row to the control, the Data Grid raises the [ValidateRow](/WPF/DevExpress.Xpf.Grid.GridViewBase.ValidateRow) event and executes the [ValidateRowCommand](/WPF/DevExpress.Xpf.Grid.GridViewBase.ValidateRowCommand). Use them to validate values, check database constraints, and insert the row to the database.

- Xaml

<section id="tabpanel_GEA6F8q-l+-7_tabid-xaml" role="tabpanel" data-tab="tabid-xaml">
<pre><code class="lang-xaml">&lt;dxg:GridControl ItemsSource=&quot;{Binding ItemsSource}&quot;&gt;
    &lt;dxg:GridControl.View&gt;
        &lt;dxg:TableView NewItemRowPosition=&quot;Top&quot;
                       ValidateRowCommand=&quot;{Binding ValidateRowCommand}&quot; /&gt;
&lt;/dxg:GridControl&gt; 
</code></pre></section>

- C#
- VB.NET

<section id="tabpanel_GEA6F8q-l+-8_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code class="lang-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();
}
</code></pre></section>
<section id="tabpanel_GEA6F8q-l+-8_tabid-vb" role="tabpanel" data-tab="tabid-vb" aria-hidden="true" hidden="hidden">
<pre><code class="lang-vb">&lt;DevExpress.Mvvm.DataAnnotations.Command&gt;
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 
</code></pre></section>

### Remove Rows

Call the [GridViewBase.DeleteRow](/WPF/DevExpress.Xpf.Grid.GridViewBase.DeleteRow%28System.Int32%29) / [TreeListView.DeleteNode](/WPF/DevExpress.Xpf.Grid.TreeListView.DeleteNode.overloads) method to delete the specified row. The row is identified by its [handle](/WPF/6322/controls-and-libraries/data-grid/grid-view-data-layout/rows-and-cards/obtain-row-handles) – a non-negative integer value.

**Commands**: [DeleteFocusedRow](/WPF/DevExpress.Xpf.Grid.DataViewCommandsBase.DeleteFocusedRow) and [DeleteSelectedRows](/WPF/DevExpress.Xpf.Grid.DataViewCommandsBase.DeleteSelectedRows)

- XAML

<section id="tabpanel_GEA6F8q-l+-9_tabid-xaml" role="tabpanel" data-tab="tabid-xaml">
<pre><code class="lang-xaml">&lt;dxg:GridControl x:Name=&quot;grid&quot; AutoGenerateColumns=&quot;AddNew&quot; ItemsSource=&quot;{Binding PersonList}&quot;&gt;
    &lt;dxg:GridControl.View&gt;
        &lt;dxg:TableView x:Name=&quot;view&quot;/&gt;
    &lt;/dxg:GridControl.View&gt;
&lt;/dxg:GridControl&gt;
&lt;!-- --&gt;
&lt;Button Click=&quot;deleteRow&quot;&gt;Delete the Focused Row&lt;/Button&gt;
</code></pre></section>

- C#
- VB.NET

<section id="tabpanel_GEA6F8q-l+-10_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code class="lang-csharp">void deleteRow(object sender, RoutedEventArgs e) {
    view.DeleteRow(view.FocusedRowHandle);
}
</code></pre></section>
<section id="tabpanel_GEA6F8q-l+-10_tabid-vb" role="tabpanel" data-tab="tabid-vb" aria-hidden="true" hidden="hidden">
<pre><code class="lang-vb">Private Sub deleteRow(ByVal sender As Object, ByVal e As RoutedEventArgs)
    view.DeleteRow(view.FocusedRowHandle)
End Sub
</code></pre></section>

![](/WPF/images/new-tem-row-deleting.png)

[View Example: How to Add and Remove Rows in Code](https://github.com/DevExpress-Examples/wpf-data-grid-add-and-remove-rows-in-code)

After a delete operation is executed, the Data Grid raises the [ValidateRowDeletion](/WPF/DevExpress.Xpf.Grid.GridViewBase.ValidateRowDeletion) / [ValidateNodeDeletion](/WPF/DevExpress.Xpf.Grid.TreeListView.ValidateNodeDeletion) events and calls the [ValidateRowDeletionCommand](/WPF/DevExpress.Xpf.Grid.GridViewBase.ValidateRowDeletionCommand) / [ValidateNodeDeletionCommand](/WPF/DevExpress.Xpf.Grid.TreeListView.ValidateNodeDeletionCommand). Use them to validate rows, check database constraints, and delete rows from the database.

- C#
- VB.NET

<section id="tabpanel_GEA6F8q-l+-11_tabid-csharp" role="tabpanel" data-tab="tabid-csharp">
<pre><code class="lang-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();
} 
</code></pre></section>
<section id="tabpanel_GEA6F8q-l+-11_tabid-vb" role="tabpanel" data-tab="tabid-vb" aria-hidden="true" hidden="hidden">
<pre><code class="lang-vb">&lt;DevExpress.Mvvm.DataAnnotations.Command&gt;
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 
</code></pre></section>

See Also

[Obtain and Set Cell Values in Code](/WPF/6150/controls-and-libraries/data-grid/data-editing-and-validation/modify-cell-values/obtain-and-set-cell-values-in-code)

[Input Validation](/WPF/7358/controls-and-libraries/data-grid/data-editing-and-validation/input-validation)

[How to Initialize a New Row when the Editor is Shown](https://github.com/DevExpress-Examples/out-of-maintenance-wpf-grid-initialize-new-item-row)