Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF ListView: Changing ItemsSource does not change ListView

Tags:

I am using a ListView control to display some lines of data. There is a background task which receives external updates to the content of the list. The newly received data may contain less, more or the same number of items and also the items itself may have changed.

The ListView.ItemsSource is bound to an OberservableCollection (_itemList) so that changes to _itemList should be visible also in the ListView.

_itemList = new ObservableCollection<PmemCombItem>(); _itemList.CollectionChanged += new NotifyCollectionChangedEventHandler(OnCollectionChanged); L_PmemCombList.ItemsSource = _itemList; 

In order to avoid refreshing the complete ListView I do a simple comparison of the newly retrieved list with the current _itemList, change items which are not the same and add/remove items if necessary. The collection "newList" contains newly created objects, so replacing an item in _itemList is correctly sending a "Refresh" notification (which I can log by using the event handler OnCollectionChanged of the 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); 

My problem is that if many items are changed in this loop, the ListView is NOT refreshing and the data on screen stay as they are...and this I don't understand.

Even a simpler version like this (exchanging ALL elements)

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

is not working properly

Any clue on this?

UPDATE

If I call the following code manually after updating all elements, everything works fine

OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); 

But of course this causes the UI to update everything which I still want to avoid.

like image 239
Danny1075 Avatar asked Jan 08 '14 12:01

Danny1075


Video Answer


2 Answers

After a change, you can use the following to refresh the Listview, it's more easy

listView.Items.Refresh(); 
like image 111
matthewpepper Avatar answered Sep 18 '22 13:09

matthewpepper


This is what I had to do to get it to work.

MyListView.ItemsSource = null; MyListView.ItemsSource = MyDataSource; 
like image 26
Xopher Avatar answered Sep 17 '22 13:09

Xopher