WPF CollectionChanged 事件 OldItems.Count

WPF CollectionChanged Event OldItems.Count

我有一个 ObservableCollection 并附加到 CollectionChanged 事件:

void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    if (e.Action == NotifyCollectionChangedAction.Add)
    {
        for (int i = 0; i < e.NewItems.Count; i++)
        {
            int id = -1 * i;
            DocumentWatchList d = (DocumentWatchList)e.NewItems[i];
            d.UID = id;
            _dataDc.DocumentWatchLists.InsertOnSubmit(d);
        }
    }
    else if (e.Action == NotifyCollectionChangedAction.Remove)
    {
        for (int i = 0; i < e.OldItems.Count; i++)
        {
            DocumentWatchList d = (DocumentWatchList)e.OldItems[i];
            _dataDc.DocumentWatchLists.DeleteOnSubmit(d);
        }
    }
    _dataDc.SubmitChanges();
}

我的集合绑定到数据网格,并按预期调用了视图模型代码(上方)。当我 select 多行并点击删除时,我希望 OldItems 集合将包含我 selected (n) 的行数。然而,实际发生的是该事件被调用 n 次,每次 OldItems 集合计数为 1。那么在什么情况下 OldItems 集合包含超过 1 个项目?这种行为是来自数据网格控件,还是 ObservableCollection.CollectionChanged 的工作方式?

出于某种原因,ObservableCollection 不支持包含多个项目的 NotifyCollectionChanged 事件。

你可以这样做:

OnCollectionChanged(
    new NotifyCollectionChangedEventArgs(
        NotifyCollectionChangedAction.Remove, singleItem));

但不是这个:(你会得到一个 NotSupportedException

 OnCollectionChanged(
    new NotifyCollectionChangedEventArgs(
        NotifyCollectionChangedAction.Remove, multipleItems));

我想不出 e.OldItems.Count 会大于 0 的任何情况。

Here 是一篇关于它的好文章,其中有人出于性能目的实际实现了对多个项目的处理。

如果您看一下 observable 集合为您提供的界面,您就已经知道您将获得什么:

https://msdn.microsoft.com/en-us/library/ms668604%28v=vs.110%29.aspx

基本上它不提供任何方式一次插入或删除多个项目。所以这实际上意味着你可以清除整个集合,但是如果你需要说删除 2 个项目而集合中有 6 个项目,你将不得不一个一个地删除它们。这就是数据网格在您的情况下将执行的操作,但假设您要实现自己的数据网格,您将被迫以相同的方式执行此操作。

为了使答案完整,我必须补充一点,有一种方法可以获得已删除列表中的多个项目,但只能通过清除集合。

替换集合中的项目也是可能的,通过使用索引运算符,您甚至可以用项目本身替换项目。我尝试了这个并且有效,在这种情况下,您将在删除的集合和插入的集合中获得相同的项目,但也会在此处逐一获得。

您当然可以创建自己的可观察集合实现来解决这些问题。但我认为您也需要数据网格的不同实现,它将使用您自定义的新批量插入或批量删除操作。