Xamarin.Forms - ListView does not update when data changes

Problem: data changes, but ListView does not update

I have a ListView whose ItemsSource is set

<ListView ItemsSource="{Binding ContactsGrouped}" 

When I click the button, I update the query to return records containing the letters "Je". I see that the right thing is returning, and that ContactsGrouped is being updated, but the user interface is not changing.

 public ObservableCollection<Grouping<string, Contact>> ContactsGrouped { get; set; } 

where Grouping is as follows:

 public class Grouping<K, T> : ObservableCollection<T> { public K Key { get; private set; } public Grouping ( K key, IEnumerable<T> items ) { Key = key; foreach ( var item in items ) this.Items.Add( item ); } } 

Given that I am using ObservableCollections, I expect the list to be redrawn. Am I missing something?

+7
xamarin xamarin.forms
source share
2 answers

It turns out that when implementing INotifyPropertyChanged, the list will still not be updated when it is filtered. However, smoothing out code that populates the list in the virtual machine and then calls that code in the OnTextChanged method (followed by a call to reset the ItemsSource) does the trick.

  public void OnTextChanged ( object sender, TextChangedEventArgs e ) { vm.PopulateContacts( vm.CurrentDataService ); ContactListView.ItemsSource = vm.ContactsGrouped; } 

The PopulateContacts method looks like this (abbreviated) ...

  // setup // Get the data var sorted = from contact in contacts orderby contact.FullName group contact by contact.FirstInitial into contactGroup select new Grouping<string, Contact> ( contactGroup.Key, contactGroup ); contactsGrouped = new ObservableCollection<Grouping<string, Contact>> ( sorted ); 

It works and is reasonably clean and verifiable.

+1
source share

I assume that the Grouping class is used from ViewModel. In this case, the ViewModel must implement the INotifyPropertyChanged interface, for example:

 #region INotifyPropertyChanged implementation public event PropertyChangedEventHandler PropertyChanged; public void OnPropertyChanged ([CallerMemberName]string propertyName = null) { if (PropertyChanged != null) { PropertyChanged (this, new PropertyChangedEventArgs (propertyName)); } } #endregion 

While you call the OnPropertyChnaged method when setting the property, you will get the binding results.

+1
source share

All Articles