WPF DataGrid删除IEditableCollectionView.CancelNew()上的NewItemPlaceholder

Sta*_*hev 6 .net c# wpf datagrid mvvm

概观

我正在开发一个WPF应用程序(使用.NET 4.5),其中一部分涉及在DataGrid中显示一些数据.
用户可以在DataGrid中添加新行,并通过其他位置的按钮删除一行.

当用户开始添加无法提交的新行然后按下删除按钮时,我遇到了问题.
应取消新行并将DataGrid重置为其先前的状态.
但是,DataGrid的NewItemPlaceholder行将被删除,并且不再显示.

我做了一个示例项目来演示这个问题.
是一个简短的截屏视频.
就是示例应用程序的样子.

重现:

  1. 双击最上面一行的价格单元格
  2. 输入无效数字以通过例外触发验证
  3. (可选)选择另一行
  4. 单击"删除"按钮

viewmodel获取ObservableCollection中的数据,ObservableCollection用作集合视图的源.我有一个简单的命令连接到删除按钮.如果用户正在添加项目(IEditableCollectionView.IsAddingNew),我尝试.CancelNew()在collectionView上取消操作.但是,当命令完成时,DataGrid已将其NewItemPlaceholder删除.

到目前为止,我已经尝试过:

  • 触发DataGrid以通过设置再次显示占位符dataGrid.CanUserAddRows = true,这有点修复了问题,但这是一个可怕的解决方法并且它有问题,之后占位符不可编辑.
  • 从源集合中删除无效项: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>
Run Code Online (Sandbox Code Playgroud)

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; }
    }
}  
Run Code Online (Sandbox Code Playgroud)

Cha*_*ton 2

那这个呢:

private void OnDeleteCommandExecuted()
{
    if (this.Products.IsAddingNew)
    {
        this.Products.CancelNew();
        this.Products.AddNew();
    }
}
Run Code Online (Sandbox Code Playgroud)

您仍然会删除输入错误的行,但会添加一个新的(大部分)空行。尽管我确信它可以修复,但唯一的问题是您0在数字列中获得默认值而不是null.