我正在使用 ListView
控件来显示一些数据行。有一个后台任务接收列表内容的外部更新。新接收到的数据可能包含数量较少、较多或相同数量的项,并且项本身可能已更改。
ListView.ItemsSource
绑定到 ObservableCollection
(_itemList),以便对 _itemList 的更改也应在 ListView
中可见。
_itemList = new ObservableCollection<PmemCombItem>();
_itemList.CollectionChanged += new NotifyCollectionChangedEventHandler(OnCollectionChanged);
L_PmemCombList.ItemsSource = _itemList;
为了避免刷新整个 ListView,我会简单比较新检索到的列表和当前的 _itemList,更改不同的项并在必要时添加/删除项。集合“newList”包含新创建的对象,因此替换_itemList中的项目将正确发送“刷新”通知(我可以使用ObservableCollection的事件处理程序OnCollectionChanged
记录它)。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);
}
无法正常工作
有什么线索吗?
更新
如果我在更新所有元素后手动调用以下代码,则一切正常运行。
OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
当然,这会导致用户界面更新所有内容,我仍然希望避免这种情况。
Dispatcher.Invoke
而不是异步的Dispatcher.BeginInvoke
吗? - Clemens