通知集合更改操作重置值是什么?

16
我有一个可观察集合...SelectableDataContext<T>..而在泛型类SelectableDataContext<T>中有两个私有成员变量
  1. 私有的T项。
  2. 私有布尔值isSelected。
当IsSelected属性更改时...我的集合的更改属性没有触发。
我认为它应该触发...因为它在INotifyCollectionChangedAction中被重置。
3个回答

45

虽然这是一个旧问题,但为了任何可能通过搜索找到此问题的人的利益,我想说:

NotifyCollectionChangedAction.Reset 表示 "集合的内容发生了重大变化"。当你在基础可观察集合上调用 Clear() 时,就会触发 Reset 事件。

使用 Reset 事件时,你无法在 NotifyCollectionChangedEventArgs 参数中获取 NewItemsOldItems 集合。

这意味着最好使用事件的 "sender" 来获取对修改后的集合的引用并直接使用它,即假定它是一个新列表。

这样的一个例子可能是:

((INotifyCollectionChanged)stringCollection).CollectionChanged += new NotifyCollectionChangedEventHandler(StringCollection_CollectionChanged);
  ...

void StringCollection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    switch (e.Action)
    {
        case NotifyCollectionChangedAction.Add:
            foreach (string s in e.NewItems)
            {
                InternalAdd(s);
            }
            break;

        case NotifyCollectionChangedAction.Remove:
            foreach (string s in e.OldItems)
            {
                InternalRemove(s);
            }
            break;

        case NotifyCollectionChangedAction.Reset:
            ReadOnlyObservableCollection<string> col = sender as ReadOnlyObservableCollection<string>;
            InternalClearAll();
            if (col != null)
            {
                foreach (string s in col)
                {
                    InternalAdd(s);
                }
            }
            break;
    }
}

有关Reset事件的讨论可以在这里找到:清空ObservableCollection时,e.OldItems中没有任何项


3
微软更改了Reset的定义。现在它的意思是:“集合的内容已被清除。” https://learn.microsoft.com/en-us/dotnet/api/system.collections.specialized.notifycollectionchangedaction?view=netframework-4.7.2 - kjbartel
2
不再是这样了。它已被澄清为“发生了巨大变化”,这可能意味着澄清,也可能意味着每个元素都发生了改变。请参见https://github.com/dotnet/dotnet-api-docs/issues/3253 - gix
这意味着如果您正在使用它来添加/删除项本身的PropertyChanged处理程序,则需要在后台维护第二个列表,以便在Reset到来时具有OldItems。如果您只是使用ObservableCollection并从不调用Clear,那么这并不是什么大问题,但绝对是您需要牢记的事情。 - Patrick

1

INotifyCollectionChangedINotifyPropertyChanged之间有所不同。

当对象中的属性值更改时,应使用INotifyPropertyChanged接口实现通知其他人。

另一方面,当集合中的项目数量项目本身发生更改时,应使用INotifyCollectionChanged实现通知其他人。

现在,在您的情况下,集合中对象的属性值更改。这应该引发PropertyChanged事件,而不是CollectionChanged事件。


-1

只有在通过添加新项或从集合中删除现有项来修改集合时,才会触发集合更改。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接