web-dev-qa-db-ja.com

Observable Collection交換アイテム

ObservableCollectionがあります。コレクションにアイテムを追加したり、コレクションからアイテムを削除したりできます。ただし、コレクション内の既存のアイテムを置き換えることはできません。アイテムを置き換えて、バインドされたコンポーネントに反映する方法があります。

System.Collections.Specialized.NotifyCollectionChangedAction.Replace

誰でも私にこれを達成する方法を教えてもらえますか?

26
thewayman
collection[someIndex] = newItem;
55
SLaks

更新:インデクサーはオーバーライドされたSetItemを使用し、変更について通知します。

インデクサーの使用に関する答えは、間違っているかもしれないと思います。なぜなら、質問はreplace and notifyに関するものだったからです。

明確にするために:_ObservableCollection<T>_は、ベースの_Collection<T>_クラスのインデクサーを使用します。これは、_List<T>_のラッパーであり、Tの単純な配列のラッパーです。 ObservableCollection の実装では、インデクサーメソッドのオーバーライドはありません。

したがって、インデクサーを使用して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);
        }
_

境界をチェックし、基になるListクラスのインデクサーを使用するSetItemを呼び出すだけです。

_protected virtual void SetItem(int index, T item) {
        items[index] = item;
    }
_

割り当て中、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);
    }
_

割り当て後は、OnCollectionChangedメソッドを呼び出します。このメソッドは、_NotifyCollectionChangedAction.Replace_アクションパラメータを使用してCollectionChangedイベントを発生させます。

_    protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
    {
        if (CollectionChanged != null)
        {
            using (BlockReentrancy())
            {
                CollectionChanged(this, e);
            }
        }
    }
_

結論として、ObservableCollectionから継承されたカスタムクラスとReplaceメソッドを使用するアイデアは、試してみる価値があるbase.SetItem()を呼び出します。

3