【问题标题】:WPF DataGrid removing NewItemPlaceholder on IEditableCollectionView.CancelNew()WPF DataGrid 删除 IEditableCollectionView.CancelNew() 上的 NewItemPlaceholder
【发布时间】:2015-07-02 00:21:20
【问题描述】:

概述

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

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

我制作了一个 sample project 来演示该问题。
Here 也是一个简短的截屏视频。
This 是示例应用程序的样子。

复制:

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

代码

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

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

  • Triggering the 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>

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; }
    }
}  

【问题讨论】:

  • 你的问题解决了吗?因为我也有同样的问题
  • @Jamaxack 我切换到 Telerik RadGridView,因为当时这对我来说是一个选项。也看看这个,如果它有帮助(我只是不记得它是否与这篇文章相同,但我记得它是相关的):connect.microsoft.com/VisualStudio/feedback/details/1465806/…

标签: c# .net wpf mvvm datagrid


【解决方案1】:

这个呢:

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

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

【讨论】:

  • 谢谢,我也试过了。它看起来没问题(除了必须解决零问题),但问题是当您之后双击新行时,它不会进入编辑模式。知道为什么吗?
  • @Stanislav 问题是在_.CancelNew(); _.AddNew(); 之后,NewItemPlaceHolder 不再是DataGrid 中的最后一行。它仍然存在于可视化树中,但不再可见。
猜你喜欢
  • 2011-09-17
  • 1970-01-01
  • 2019-06-22
  • 2014-08-22
  • 2012-05-20
  • 2013-08-15
  • 1970-01-01
  • 2023-03-24
  • 1970-01-01
相关资源
最近更新 更多