wpf Observable 集合替换项目
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6873533/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Observable Collection replace item
提问by thewayman
I have a ObservableCollection
, I can add and remove item from the collection. But I can't replace an existing item in the collection. There is a way to replace an item and reflect that on my bound components.
我有一个ObservableCollection
,我可以从集合中添加和删除项目。但我无法替换集合中的现有项目。有一种方法可以替换一个项目并将其反映在我绑定的组件上。
System.Collections.Specialized.NotifyCollectionChangedAction.Replace
Can anyone please show me how to accomplish this?
谁能告诉我如何做到这一点?
回答by SLaks
collection[someIndex] = newItem;
回答by Mikhail Tumashenko
Updated: Indexer uses overridden SetItem and notifies about changes.
更新:索引器使用覆盖的 SetItem 并通知更改。
I think the answer about using indexer may be wrong, because the question was about replace and notify.
我认为关于使用索引器的答案可能是错误的,因为问题是关于替换和通知的。
Just to clarify: ObservableCollection<T>
uses indexer from its base Collection<T>
class, which in turn is a wrapper of List<T>
, which is a wrapper of simple array of T
. And there's no override for indexer method in ObservableCollectionimplementation.
只是为了澄清:ObservableCollection<T>
使用来自其基Collection<T>
类的索引器,它又是 的包装器List<T>
,它是T
.的简单数组的包装器。在ObservableCollection实现中没有覆盖索引器方法。
So when you use indexer to replace an item in ObservableCollectionit invokes the following code from Collectionclass:
因此,当您使用索引器替换ObservableCollection 中的项目时,它会调用Collection类中的以下代码:
public T this[int index] {
get { return items[index]; }
set {
if( items.IsReadOnly) {
ThrowHelper.ThrowNotSupportedException(ExceptionResource.NotSupported_ReadOnlyCollection);
}
if (index < 0 || index >= items.Count) {
ThrowHelper.ThrowArgumentOutOfRangeException();
}
SetItem(index, value);
}
It just checks boundaries and calls SetItem that uses indexer of underlying Listclass:
它只是检查边界并调用使用底层List类索引器的 SetItem :
protected virtual void SetItem(int index, T item) {
items[index] = item;
}
During assignment there is no call to the CollectionChanged
event, because underlying collections know nothing of it.
在分配期间,不会调用该CollectionChanged
事件,因为底层集合对此一无所知。
But when you use SetItem
method, it is called from ObservableCollection class:
但是当你使用SetItem
方法时,它是从 ObservableCollection 类中调用的:
protected override void SetItem(int index, T item)
{
CheckReentrancy();
T originalItem = this[index];
base.SetItem(index, item);
OnPropertyChanged(IndexerName);
OnCollectionChanged(NotifyCollectionChangedAction.Replace, originalItem, item, index);
}
After assignment it calls OnCollectionChanged
method, which fires CollectionChanged
event with NotifyCollectionChangedAction.Replace
action parameter.
分配后它调用OnCollectionChanged
方法,该方法CollectionChanged
使用NotifyCollectionChangedAction.Replace
动作参数触发事件。
protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
if (CollectionChanged != null)
{
using (BlockReentrancy())
{
CollectionChanged(this, e);
}
}
}
As a conclusion: the idea with custom class inherited from ObservableCollection and Replace
method that calls base.SetItem()
worth a try.
总结:继承自 ObservableCollection 的自定义类和Replace
调用方法的想法base.SetItem()
值得一试。