带有Sections的MvxCollectionViewController

时间:2014-01-27 12:59:15

标签: c# xamarin.ios mvvmcross

使用Xamarin.iOS和MvvmCross,我正在尝试创建一个包含Sections的MvxCollectionViewController,每个Section包含一个标题和一个MvxCollectionViewCell的集合(基于MvvmCross教程{{3 }})。

我已经在教程中列出了MvxCollectionViewCell的子类。我有以下Model和ViewModel层次结构(改编自教程):

public class Kitten    
{
    public string Name { get; set; }
    public string ImageUrl { get; set; }
}

每个部分的ViewModel:

public class KittenSectionViewModel : MvxViewModel
{
    private string _sectionName;
    public string SectionName
    {
        get { return _sectionName; }
        set { _sectionName = value; RaisePropertyChanged(() => SectionName); }
    }

    private List<Kitten> _kittens;
    public List<Kitten> Kittens
    { 
        get { return _kittens; }
        set { _kittens = value; RaisePropertyChanged(() => Kittens); }
    }
}

然后是所有部分的ViewModel:

public class KittensViewModel: MvxViewModel
{
    private readonly IKittenService _kittenService;

    public List<KittenSectionViewModel> KittenSections { get; set; }

    public KittensViewModel(IKittenService kittenService)
    {
        _kittenService = kittenService;
    }

    public override void Start ()
    {
        KittenSections = _kittenService.GetKittens().ToList();
    }
}

KittenCollectionCell基本不变:

public KittenCollectionCell (IntPtr handle) : base (handle)
{
    _loader = new MvxImageViewLoader(() => MainImage);

    this.DelayBind(() => {
        var set = this.CreateBindingSet<KittenCollectionCell, Kitten>();
        set.Bind(NameLabel).To(kitten => kitten.Name);
        set.Bind (_loader).To (kitten => kitten.ImageUrl);
        set.Apply();
    });
}

最后我实现了一个自定义MvxCollectionViewSource,我将其分配给CollectionView的源:

public class KittenCollectionViewSource : MvxCollectionViewSource
{
    KittensViewModel KittensViewModel { get; set; }

    public KittenCollectionViewSource (KittensViewModel kittensViewModel, UICollectionView collectionView, NSString defaultCellIdentifier) : base (collectionView, defaultCellIdentifier)
    {
        this.KittensViewModel = kittensViewModel;
    }

    public override int GetItemsCount (UICollectionView collectionView, int section)
    {
        return KittensViewModel.KittenSections [section].Kittens.Count;
    }

    public override int NumberOfSections (UICollectionView collectionView)
    {
        return KittensViewModel.KittenSections.Count;
    }

    protected override UICollectionViewCell GetOrCreateCellFor (UICollectionView collectionView, NSIndexPath indexPath, object item)
    {
        return collectionView.DequeueReusableCell (DefaultCellIdentifier, indexPath) as KittenCollectionCell;
    }
}

(完整的解决方案可在http://slodge.blogspot.co.uk/2013/05/n11-collectionview-n1-days-of-mvvmcross.html获得。)

问题是KittenCollectionCell需要绑定到Kitten,但由于模型包含在不同的视图模型中,我不知道如何告诉MvxCollectionViewSource使用内在模型?

1 个答案:

答案 0 :(得分:3)

您的来源结构看起来相当简单 - 所以我认为您所缺少的是GetItemAt覆盖 - 请参阅https://github.com/MvvmCross/MvvmCross/blob/v3.1/Cirrious/Cirrious.MvvmCross.Binding.Touch/Views/MvxCollectionViewSource.cs#L75

我认为您需要添加以下内容:

    protected override object GetItemAt(NSIndexPath indexPath)
    {
        if (KittensViewModel == null)
            return null;

        return KittensViewModel
                      .KittenSections[indexPath.Section]
                      .Kittens[indexPath.Row];
    }

您也可以将KittensViewModel实现为:

   protected KittensViewModel KittensViewModel { get { return base.ItemsSource as KittensViewModel; } }