Overview

I'm developing a WPF application (using .NET 4.5), part of which involves showing some data in a DataGrid.

The user has the ability to add a new row inside the DataGrid and delete one via a button elsewhere.

I have an issue when the user starts adding a new row that cannot be committed and then presses the delete button.

The new row should be canceled and the DataGrid reset to its previous state.

However, the DataGrid's NewItemPlaceholder row is deleted and never shown again.

I've made a sample project that demonstrates the issue.

Here is a short screencast as well.

This is what the sample app looks like.

To reproduce:

Double click the Price cell on the topmost row Enter an invalid number to trigger validation via an exception (optional) Select another row Click the delete button

Code

The viewmodel gets the data in an ObservableCollection, which is used as the source for a collection view. I have a simple command wired to the delete button. If the user is adding an item ( IEditableCollectionView.IsAddingNew ) I try to cancel the operation using .CancelNew() on the collectionView. However, when the command completes the DataGrid has its NewItemPlaceholder deleted.

So far, I've tried:

Triggering the DataGrid to make the placeholder appear again by setting dataGrid.CanUserAddRows = true , which fixes the issue somewhat, but that's a horrible workaround and it's buggy, afterwards the placeholder is not editable.

, which fixes the issue somewhat, but that's a horrible workaround and it's buggy, afterwards the placeholder is not editable. Removing the invalid item from the source collection: this.productsObservable.Remove(this.Products.CurrentAddItem as Product) .

This doesn't change the behavior, the placeholder is still removed.

. This doesn't change the behavior, the placeholder is still removed. Removing the item from the collection view: this.Products.Remove(this.Products.CurrentAddItem) .

This throws an exception, which makes sense: 'Remove' is not allowed during an AddNew or EditItem transaction.

Is there another way I can cancel the user's add AND have the NewItemPlaceholder showing?

In the sample project I'm instantiating the data inside the VM constructor for simplicity.

In reality I'm using async calls to a service, wrapping the result in ObservableCollection and the ViewModel implements INotifyPropertyChanged. The business object doesn't implement INPC.

XAML for the sample project:

<Window x:Class="WpfApplication3.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WpfApplication3" Title="MainWindow" Height="250"> <Window.DataContext> <local:ViewModel /> </Window.DataContext> <StackPanel Orientation="Vertical"> <Button Command="{Binding DeleteCommand}" Content="Delete row" /> <DataGrid ItemsSource="{Binding Products}" CanUserDeleteRows="False" CanUserAddRows="True" SelectionMode="Single"> </DataGrid> </StackPanel> </Window>

ViewModel, together with a simple Business Object: