WPF CollectionChanged事件OldItems.Count

时间:2015-03-10 20:06:04

标签: c# wpf datagrid

我有一个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();
}

我的集合绑定到一个datagrid,并且viewmodel代码(上面)按预期调用。当我选择多行并点击删除时,我希望OldItems集合将包含我选择的行数(n)。然而,实际发生的事情是该事件被调用n次,并且每次OldItems集合计数为1.那么在什么条件下OldItems集合将包含多于1个项目?这种行为是来自datagrid控件,还是ObservableCollection.CollectionChanged的工作方式?

2 个答案:

答案 0 :(得分:0)

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

你可以这样做:

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

但不是这样:(你得到NotSupportedException

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

我无法想到e.OldItems.Count大于0的任何情况。

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

答案 1 :(得分:0)

如果您看一下observable collection为您提供的界面,您已经知道将会得到什么:

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

基本上它不提供任何方法一次插入或删除多个项目。因此,这实际上意味着您可以清除整个集合,但如果您需要在集合中有6个项目时删除2个项目,则必须逐个删除它们。这是数据网格在你的情况下会做什么,但假设你要实现自己的数据网格,你将被迫以同样的方式做到这一点。

要完成答案,我必须补充说,有一种方法可以在已删除的列表中获取多个项目,但只能通过清除集合。

也可以使用索引运算符替换集合中的项目,甚至可以用自身替换项目。我&#39;我试过这个,这个工作,在这种情况下,你将在已删除的集合和插入的集合中获得相同的项目,但也在这里一个接一个。

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