Я использую элемент управления ListView
для отображения некоторых строк данных. Существует фоновая задача, которая получает внешние обновления для содержимого списка. Недавно полученные данные могут содержать меньше, больше или одинаковое количество элементов, а также сами элементы могут быть изменены.
ListView.ItemsSource
привязан к OberservableCollection
(_itemList), так что изменения в _itemList должны быть видны также в ListView
.
_itemList = new ObservableCollection<PmemCombItem>();
_itemList.CollectionChanged += new NotifyCollectionChangedEventHandler(OnCollectionChanged);
L_PmemCombList.ItemsSource = _itemList;
Чтобы избежать обновления полного списка ListView, я делаю простое сравнение недавно полученного списка с текущим _itemList, изменяя элементы, которые не являются одинаковыми, и при необходимости добавьте/удалите элементы. Коллекция "newList" содержит вновь созданные объекты, поэтому замена элемента в _itemList корректно отправляет уведомление "Обновить" (которое я могу зарегистрировать с помощью обработчика событий OnCollectionChanged
ObservableCollection`)
Action action = () =>
{
for (int i = 0; i < newList.Count; i++)
{
// item exists in old list -> replace if changed
if (i < _itemList.Count)
{
if (!_itemList[i].SameDataAs(newList[i]))
_itemList[i] = newList[i];
}
// new list contains more items -> add items
else
_itemList.Add(newList[i]);
}
// new list contains less items -> remove items
for (int i = _itemList.Count - 1; i >= newList.Count; i--)
_itemList.RemoveAt(i);
};
Dispatcher.BeginInvoke(DispatcherPriority.Background, action);
Моя проблема в том, что если в этом цикле меняются многие элементы, ListView
НЕ обновляется, а данные на экране остаются такими, какие они есть... и этого я не понимаю.
Даже более простая версия, подобная этой (замена ВСЕХ элементов)
List<PmemCombItem> newList = new List<PmemCombItem>();
foreach (PmemViewItem comb in combList)
newList.Add(new PmemCombItem(comb));
if (_itemList.Count == newList.Count)
for (int i = 0; i < newList.Count; i++)
_itemList[i] = newList[i];
else
{
_itemList.Clear();
foreach (PmemCombItem item in newList)
_itemList.Add(item);
}
работает неправильно
Какой-нибудь ключ к этому?
UPDATE
Если после обновления всех элементов я вызываю следующий код вручную, все работает отлично
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
Но, конечно, это заставляет пользовательский интерфейс обновлять все, чего я все еще хочу избежать.