Collection Observable remplacer l'article

j'ai un ObservableCollection, je peux ajouter et supprimer un élément de la collection. Mais je ne peux pas remplacer un article existant dans la collection. Il existe un moyen de remplacer un élément et de réfléchir sur ma composants liés.

System.Collections.Specialized.NotifyCollectionChangedAction.Replace
<!-Est-ce que quelqu'un peut me montrer comment accomplir ceci?

19
demandé sur Kamran Ahmed 2011-07-29 17:03:33

2 réponses

collection[someIndex] = newItem;
50
répondu SLaks 2011-07-29 13:09:06

mise à jour: L'indexeur utilise le SetItem annulé et notifie les changements.

je pense que la réponse à propos de l'utilisation d'indexation peut être mauvais, parce que la question portait sur remplacer et d'en informer.

Juste pour préciser: ObservableCollection<T> utilise l'indexeur à partir de sa base Collection<T> classe, qui à son tour est un wrapper de List<T>, qui est un wrapper de simple tableau de T. Et il n'y a pas de remplacement pour l'indexeur méthode collecte observable mise en oeuvre.

donc quand vous utilisez indexer pour remplacer un élément dans collecte observable il invoque le code suivant de Collection catégorie:

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);
        }

il ne fait que vérifier les limites et appelle SetItem qui utilise l'indexeur deListe catégorie:

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

pendant l'affectation il n'y a pas d'appel à la CollectionChanged d'événements, parce que les collections sous-jacentes ne savent rien de il.

mais quand vous utilisez SetItem méthode, il est appelé à partir de ObservableCollection de la classe:

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);
    }

Après la cession, il appelle OnCollectionChanged méthode, qui se déclenche CollectionChanged événement NotifyCollectionChangedAction.Replace paramètre d'action.

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

en conclusion: l'idée avec la classe personnalisée héritée de ObservableCollection et Replace méthode qui appelle base.SetItem() vaut la peine d'essayer.

2
répondu Mikhail Tumashenko 2015-09-22 07:14:54