我正在开发一个WPF应用程序(使用.NET 4.5),其中一部分涉及在DataGrid中显示一些数据。
用户可以在DataGrid中添加新行,并通过其他位置的按钮删除一行。
当用户开始添加无法提交的新行然后按下删除按钮时,我遇到了问题
应该取消新行并将DataGrid重置为其先前的状态
但是,DataGrid的NewItemPlaceholder
行将被删除,并且不再显示。
我做了sample project来证明这个问题 Here也是一个简短的截屏视频 This是示例应用的样子。
重现:
viewmodel获取ObservableCollection中的数据,ObservableCollection用作集合视图的源。
我有一个简单的命令连接到删除按钮。如果用户正在添加项目(IEditableCollectionView.IsAddingNew
),我尝试使用collectionView上的.CancelNew()
取消操作。但是,当命令完成时,DataGrid会删除NewItemPlaceholder
。
到目前为止,我已经尝试过了:
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>
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; }
}
}
答案 0 :(得分:2)
这个怎么样:
private void OnDeleteCommandExecuted()
{
if (this.Products.IsAddingNew)
{
this.Products.CancelNew();
this.Products.AddNew();
}
}
您仍然会删除输入错误的行,但您会添加一个新的(大部分)空行。唯一的问题,虽然我确定它的可修复性,但是您在数字列中得到的默认0
值不是null
。