Observable Collection替换项目

the*_*man 24 wpf binding replace observablecollection

我有一个ObservableCollection,我可以添加和删除集合中的项目.但我无法替换集合中的现有项目.有一种方法可以替换项目并将其反映在我的绑定组件上.

System.Collections.Specialized.NotifyCollectionChangedAction.Replace
Run Code Online (Sandbox Code Playgroud)

任何人都可以告诉我如何做到这一点?

SLa*_*aks 57

collection[someIndex] = newItem;
Run Code Online (Sandbox Code Playgroud)

  • 你不需要自己上课.你可以写`collection [someIndex] = newItem`. (5认同)

Mik*_*nko 6

更新:索引器使用重写的 SetItem 并通知更改。

我认为关于使用索引器的答案可能是错误的,因为问题是关于替换和通知的

只是为了澄清:ObservableCollection<T>使用其基Collection<T>类中的索引器,而它又是 的包装器List<T>,它是 的简单数组的包装器TObservableCollection实现中没有覆盖索引器方法。

因此,当您使用索引器替换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);
        }
Run Code Online (Sandbox Code Playgroud)

它只是检查边界并调用使用底层List类索引器的 SetItem:

protected virtual void SetItem(int index, T item) {
        items[index] = item;
    }
Run Code Online (Sandbox Code Playgroud)

在分配期间,不会调用该CollectionChanged事件,因为底层集合对此一无所知。

但是当您使用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);
    }
Run Code Online (Sandbox Code Playgroud)

分配后,它调用OnCollectionChanged方法,该方法CollectionChangedNotifyCollectionChangedAction.Replace操作参数触发事件。

    protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
    {
        if (CollectionChanged != null)
        {
            using (BlockReentrancy())
            {
                CollectionChanged(this, e);
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

结论:继承自 ObservableCollection 的自定义类和Replace调用方法的想法base.SetItem()值得一试。

  • Operator [] 使用 ObservableCollection 中的重写方法 SetItem (4认同)