WPF DataGrid removes NewItemPlaceholder in IEditableCollectionView.CancelNew ()

Overview

I am developing a WPF application (using .NET 4.5), part of which includes showing some data in a DataGrid.
The user has the ability to add a new row inside the DataGrid and delete it using the button in another place.

I have a problem when the user starts adding a new row that cannot be fixed, and then clicks the delete button.
The new row should be undone, and the DataGrid reset should be in the previous state.
However, the DataGrid row NewItemPlaceholderis deleted and is never displayed again.

I made a sample project that demonstrates the problem.
Here is a short screencast.
This is what the sample application looks like.

Playback:

  • Double-click the Price cell in the top row.
  • Please enter an invalid number to start checking with exception
  • (optional) Select a different line
  • Click the delete button

the code

The viewmodel model receives data in an ObservableCollection, which is used as a source to represent the collection. I have a simple command connected to the delete button. If the user adds an element ( IEditableCollectionView.IsAddingNew), I try to cancel the operation using .CancelNew()in the collection. However, when the command completes, the DataGrid deletes NewItemPlaceholder.

So far I have tried:

  • DataGrid, , dataGrid.CanUserAddRows = true, , buggy, .
  • : this.productsObservable.Remove(this.Products.CurrentAddItem as Product).
    , - .
  • : this.Products.Remove(this.Products.CurrentAddItem).
    , : 'Remove' is not allowed during an AddNew or EditItem transaction.

, , , NewItemPlaceholder?

VM .
, ObservableCollection, ViewModel INotifyPropertyChanged. - INPC.

XAML :

<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 -:

using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Windows.Data;
using System.Windows.Input;

namespace WpfApplication3
{
    public class ViewModel
    {
        private readonly ObservableCollection<Product> productsObservable;

        public ViewModel()
        {
            this.productsObservable = new ObservableCollection<Product>()
            {
                new Product() { Name = "White chocolate", Price = 1},
                new Product() { Name = "Black chocolate", Price = 2},
                new Product() { Name = "Hot chocolate", Price = 3},
            };

            this.Products = CollectionViewSource.GetDefaultView(this.productsObservable) as IEditableCollectionView;
            this.Products.NewItemPlaceholderPosition = NewItemPlaceholderPosition.AtBeginning;

            this.DeleteCommand = new DelegateCommand(this.OnDeleteCommandExecuted);
        }

        public ICommand DeleteCommand { get; private set; }
        public IEditableCollectionView Products { get; private set; }

        private void OnDeleteCommandExecuted()
        {
            if (this.Products.IsAddingNew)
            {
                this.Products.CancelNew();
            }
        }

    }

    public class Product
    {
        public string Name { get; set; }
        public decimal Price { get; set; }
    }
}  
+4
1

:

private void OnDeleteCommandExecuted()
{
    if (this.Products.IsAddingNew)
    {
        this.Products.CancelNew();
        this.Products.AddNew();
    }
}

, ( ) . , , , , 0 , null.

+2

Source: https://habr.com/ru/post/1584322/


All Articles