【问题标题】:Xamarin.Forms - ListView does not update when data changesXamarin.Forms - 数据更改时 ListView 不更新
【发布时间】:2014-11-25 15:05:25
【问题描述】:

问题:数据发生变化,但 ListView 没有更新

我有一个 ListView,其 ItemsSource 设置为

<ListView ItemsSource="{Binding ContactsGrouped}" 

单击按钮时,我会更新查询以仅返回包含字母“Je”的记录。我可以看到正在返回正确的内容,并且正在更新 ContactsGrouped,但 UI 没有更改。

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,我希望该列表会重绘。我错过了什么明显的东西吗?

【问题讨论】:

    标签: c# xamarin xamarin.forms


    【解决方案1】:

    我认为 Grouping 类是从 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方法就会得到绑定的结果。

    【讨论】:

      【解决方案2】:

      事实证明,在实现 INotifyPropertyChanged 时,过滤列表时仍然不会更新列表。但是,分解出填充 VM 中列表的代码,然后在 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 );
      

      这行得通,而且相当干净和可测试

      【讨论】: