当MvxCollectionViewSource的数据发生变化时,如何重绘UICollectionView?

时间:2016-07-18 14:14:38

标签: data-binding xamarin.ios mvvmcross

我正在使用Xamarin和MVVMCross来实现IOS应用程序。我正在研究的一个视图是正确显示的,但是当我硬编码被绑定到我的ViewModel内部的数据时,而不是当(因为设计和必要性)我的数据从SQLite迟到时,在视图之后只有一个不确定的时间显示。

到目前为止我正在使用和完成的内容:

  • 我的View的工作/显示故事板,其中包含 UICollectionView 内部(在下面的代码中称为 CollectionView
  • 在我的视图中也能正确显示的每个 UICollectionViewCell 的自定义布局和XIB文件
  • 仅当在调用 ViewDidLoad()时完全填充ViewModel数据时,该视图才能正常工作和显示。

问题:

  • 我的 ViewModel 中的数据在不确定的时间内由模型的数据库更新,同时视图很乐意显示。当我如下所示绑定数据(并尝试双向/单向绑定等)时,我的视图没有得到更新,因为最终数据稍后会出现。

我似乎无法做到:

  • 重绘 UICollectionView 或者刷新 下面的 MvxCollectionViewSource 确保随着ViewModel的数据发生变化,我实际上可以重绘 UICollectionView 并显示我的 具有新数据和更新数据的自定义单元格。

THE CODE(TM)

CollectionView 单元格如下实现。我在线跟踪了所有的例子,并从Stuart Bloke和他的小猫那里得到了确保我完全实现所有模式:

[Register("MyCell")]
public partial class MyCell : MvxCollectionViewCell
{
    public static readonly UINib Nib = UINib.FromName("MyCell", NSBundle.MainBundle);
    public static readonly NSString Key = new NSString("MyCell");

    public MyCell(IntPtr handle) : base(handle)
    {
        this.DelayBind(() => {
            var set = this.CreateBindingSet<MyCell, SomeModelClass>();
            set.Bind(Label1).To(item => item.Label1);
            set.Bind(Label2).To(item => item.Label2);
            set.Apply();
        });
    }

    public static MyCell Create()
    {
        return (MyCell)Nib.Instantiate(null, null)[0];
    }
}

View中的 ViewDidLoad()看起来像这样:

CollectionView.RegisterNibForCell(MyCell.Nib, MyCell.Key);
var source = new MvxCollectionViewSource(CollectionView, MyCell.Key);
CollectionView.Source = source;

var set = this.CreateBindingSet<MyView, MyViewModel>();
set.Bind(source).To(vm => vm.ListOfStuff);
set.Apply();

CollectionView.ReloadData();

NB!上面显示的 ListOfStuff 实际上只是一个包含2个字符串的自定义类的List。

TL:DR:我在调用上述代码时不知道 ListOfStuff 的值。当我在ViewModel中对它们进行硬编码时,我感到高兴。如果我不这样做,我就不会,即使数据在以后正确更新。

我现在联系你,众包的大脑神经元......

1 个答案:

答案 0 :(得分:0)

不应使用List<T>使用ObservableCollection<T>,而应将新项目添加到CollectionView

UI需要知道集合何时发生了变化。 ObservableCollection<T>实现INotifyCollectionChangedINotifyPropertyChanged,并在集合发生变化时与UI进行通信。

如果您使用的是ReloadData(),则不应再需要ObservableCollection<T>

添加IEnumerable<T>

的范围时,此扩展方法可能有用
public static class ObservableCollectionExtensionMethod
{
    public static void AddRange<TSource>(this ObservableCollection<TSource> source, IEnumerable<TSource> collection)
    {
        foreach (var i in collection) source.Add(i);
    }
}