В Xamarin.Forms-ListView не обновляется при изменении данных

проблема: изменения данных, но ListView не обновляется

у меня есть ListView, для которого ItemsSource установлено значение

<ListView ItemsSource="{Binding ContactsGrouped}" 

при нажатии кнопки Я обновляю запрос, чтобы возвращать только записи, содержащие буквы "Je". Я вижу, что возвращается правильная вещь, и что ContactsGrouped обновляется, но пользовательский интерфейс не меняется.

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

где группировка выглядит так:

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

учитывая, что я использую ObservableCollections, я ожидаю, что список будет перерисован. Я упускаю что-то очевидное?

2 ответов


Я предполагаю, что класс группировки используется из ViewModel. В этом случае ViewModel должен реализовать интерфейс INotifyPropertyChanged, такой как ниже:

#region INotifyPropertyChanged implementation

public event PropertyChangedEventHandler PropertyChanged;

public void OnPropertyChanged ([CallerMemberName]string propertyName = null)
{
    if (PropertyChanged != null) {
        PropertyChanged (this, new PropertyChangedEventArgs (propertyName));
    }
}

#endregion

пока вы называете OnPropertyChnaged метод установки свойства, то вы получите результаты привязки.


оказывается, что при реализации INotifyPropertyChanged все равно не будет обновлять список при его фильтрации. Однако факторизация кода, который заполняет список в виртуальной машине, а затем вызов этого кода в методе OnTextChanged (с последующим вызовом сброса ItemsSource) делает трюк.

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

метод PopulateContacts выглядит следующим образом (сокращенный)...

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

это работает, и достаточно чистый и проверяемый