wpf - sirve - Colección Observable reemplazar artículo
wpf converter binding (2)
collection[someIndex] = newItem;
Tengo una ObservableCollection
, puedo agregar y eliminar elementos de la colección. Pero no puedo reemplazar un elemento existente en la colección. Hay una manera de reemplazar un artículo y reflejarlo en mis componentes vinculados.
System.Collections.Specialized.NotifyCollectionChangedAction.Replace
¿Puede alguien por favor mostrarme cómo lograr esto?
Actualizado: Indexer usa SetItem anulado y notifica sobre cambios.
Creo que la respuesta sobre el uso del indexador puede ser incorrecta , porque la pregunta era sobre reemplazar y notificar .
Solo para aclarar: ObservableCollection<T>
usa un indexador de su clase Collection<T>
, que a su vez es un contenedor de List<T>
, que es un contenedor de una matriz simple de T
Y no hay anulación para el método del indexador en la implementación de ObservableCollection .
Entonces, cuando usa indexer para reemplazar un elemento en ObservableCollection , invoca el siguiente código de la clase 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);
}
Simplemente verifica los límites y llama a SetItem que usa el indexador de la clase List subyacente:
protected virtual void SetItem(int index, T item) {
items[index] = item;
}
Durante la asignación, no hay llamadas al evento CollectionChanged
, porque las colecciones subyacentes no saben nada al respecto.
Pero cuando SetItem
método SetItem
, se llama desde la clase 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);
}
Después de la asignación, llama OnCollectionChanged
método OnCollectionChanged
, que NotifyCollectionChangedAction.Replace
evento CollectionChanged
con el parámetro de acción NotifyCollectionChangedAction.Replace
.
protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
if (CollectionChanged != null)
{
using (BlockReentrancy())
{
CollectionChanged(this, e);
}
}
}
Como conclusión: vale la pena probar la idea de la clase personalizada heredada de ObservableCollection y el método Replace
que llama a base.SetItem()
.