WPF DataGrid删除IEditableCollectionView.CancelNew()上的NewItemPlaceholder
概观
我正在开发一个WPF应用程序(使用.NET 4.5),其中一部分涉及在DataGrid中显示一些数据。
用户可以在DataGrid中添加新行,并通过其他位置的按钮删除一行。
当用户开始添加无法提交的新行然后按下删除按钮时,我遇到了问题。
应取消新行,并将DataGrid重置为其先前的状态。
但是,DataGrid的NewItemPlaceholder
行将被删除,并且不再显示。
我做了一个示例项目来演示这个问题。
这是一个简短的截屏video。
这就是示例应用程序的样子。
重现:
- 双击最上面一行的价格单元格
- 输入无效的数字以通过例外触发validation
- (可选)选择另一行
- 单击“删除”按钮
码
viewmodel获取ObservableCollection中的数据,ObservableCollection用作集合视图的源。 我有一个简单的命令连接到删除按钮。 如果用户正在添加项目( IEditableCollectionView.IsAddingNew
),我尝试在collectionView上使用.CancelNew()
取消操作。 但是,当命令完成时,DataGrid NewItemPlaceholder
删除其NewItemPlaceholder
。
到目前为止,我已经尝试过:
- 触发DataGrid以通过设置
dataGrid.CanUserAddRows = true
再次显示占位符,这有点修复了问题,但这是一个可怕的解决方法并且它是错误的,之后占位符不可编辑。 - 从源集合中删除无效项:
this.productsObservable.Remove(this.Products.CurrentAddItem as Product)
。
这不会改变行为,占位符仍然被删除。 - 从集合视图中删除该项:
this.Products.Remove(this.Products.CurrentAddItem)
。
这会引发exception,这是有道理的:'Remove' is not allowed during an AddNew or EditItem transaction.
有没有其他方法可以取消用户的添加并显示NewItemPlaceholder?
在示例项目中,为了简单起见,我在VM构造函数中实例化数据。
实际上我正在使用对服务的异步调用,将结果包装在ObservableCollection中,而ViewModel实现了INotifyPropertyChanged。 业务对象未实现INPC。
示例项目的XAML:
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 productsObservable; public ViewModel() { this.productsObservable = new ObservableCollection() { 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; } } }
那这个呢:
private void OnDeleteCommandExecuted() { if (this.Products.IsAddingNew) { this.Products.CancelNew(); this.Products.AddNew(); } }
您仍将删除输入错误的行,但您将添加一个新的(大部分)空行。 唯一的问题,虽然我确定它的可修复性,是你在数值列中得到默认的0
值而不是null
。