Ответ 1
collection[someIndex] = newItem;
У меня есть ObservableCollection
, я могу добавить и удалить элемент из коллекции. Но я не могу заменить существующий элемент в коллекции. Существует способ заменить элемент и отразить это на моих связанных компонентах.
System.Collections.Specialized.NotifyCollectionChangedAction.Replace
Может ли кто-нибудь показать мне, как это сделать?
collection[someIndex] = newItem;
Обновлено: Indexer использует переопределенный SetItem и уведомляет об изменениях.
Я думаю, что ответ об использовании индексатора может быть неправильным, потому что вопрос был о заменять и уведомлять.Дел >
Просто пояснить: ObservableCollection<T>
использует indexer из своего базового класса Collection<T>
, который, в свою очередь, является оберткой List<T>
, которая является оболочкой простого массива T
. И нет переопределения для метода индексатора в ObservableCollection реализации.
Поэтому, когда вы используете индекс для замены элемента в ObservableCollection, он вызывает следующий код из класса Коллекция:
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);
}
Он просто проверяет границы и вызывает SetItem, который использует индексатор базового класса List:
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
, который запускает событие CollectionChanged
с параметром действия NotifyCollectionChangedAction.Replace
.
protected virtual void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
{
if (CollectionChanged != null)
{
using (BlockReentrancy())
{
CollectionChanged(this, e);
}
}
}
В качестве вывода: идея с пользовательским классом, унаследованным от метода ObservableCollection и Replace
, который вызывает base.SetItem()
, стоит попробовать.