MVVMCross具有多种CollectionViewCell类型和数据绑定问题

时间:2018-08-03 07:22:05

标签: xamarin xamarin.ios mvvmcross

我是MVVMCross的新手,从理论上讲,直到我开始使用UICollectionViewCell时,它并不难做到

我的视图控制器中有多个部分,每个部分都应绑定到不同类型的数据,该怎么办?

在ViewModel中,它具有一个列表和一个属性,我想使用以下属性填充我的自定义单元格

List<ClassForCell1> list;
private int _valueForCell2;

public int ValueForCell2
{
    get => _valueForCell2;
    set => _valueForCell2 = value;
}

在MySource类中,我注册了不同类型的Cell,看起来像这样

public MySource(UICollectionView collectionView, ViewModel viewModel) : base(collectionView)
{
    _viewModel = viewModel;
    collectionView.RegisterClassForCell(typeof(CustomCell1), CustomCell1.Key);
    collectionView.RegisterNibForCell(CustomCell2.Nib, CustomCell2.Key);
    //... some other cell registration
}

这是我的细胞

protected CustomCell1(IntPtr handle) : base(handle)
{
    this.DelayBind(() =>
    {
        var set = this.CreateBindingSet<CustomCell1, ClassForCell1>();
        set.Bind(NameLabel).To(m => m.name);
        set.Apply();
    });
}

protected CustomCell2(IntPtr handle) : base(handle)
{
    this.DelayBind(() =>
    {
        // how to bind this one?
        var set = this.CreateBindingSet<CustomCell2, ???>();
        set.Bind(NameLabel).To(a view model's value); // ValueForCell2 in ViewModel
        set.Apply();
    });
}

我的问题是:

  1. 如何将viewModel的特定属性或列表绑定到特定的单元格或部分?

这是我的ViewController中的代码段,用于绑定ViewController和ViewModel,似乎根本不起作用

var source = new MySource(MyCollectionView, MyViewModel);
var set = this.CreateBindingSet<MyViewController, MyViewModel>();
  1. 对于CustomCell2,如何绑定标签的Text属性以查看模型的属性? (ValueForCell2)

1 个答案:

答案 0 :(得分:1)

每个单元格都需要有单独的ViewModel,并且您的父级ViewModel需要公开要显示的项目列表。

由于要显示两种不同类型的单元格,因此需要一个通用的基类来描述它们。为此,您可以这样创建BaseCellViewModel类:

public abstract class BaseCellViewModel : MvxViewModel
{
    private string _name;
    public string Name {
        get { return _name; }
        set { SetProperty(ref _name, value); }
    }
}

现在您已经有了基类设置,您可以为要显示的每个单元格创建ViewModel:

public class FirstCustomCellViewModel : BaseCellViewModel
{
  //add any properties that are specific to the first type of cell
}

public class SecondCustomCellViewModel : BaseCellViewModel
{
  //add any properties that are specific to the second type of cell
}

现在已经设置了单元格的所有ViewModel,您可以像这样设置父ViewModel:

public class ListViewModel : MvxViewModel
{
    private ObservableCollection<BaseCellViewModel> _listItems { get; set; }
    public virtual ObservableCollection<BaseCellViewModel> ListItems {
        get { return _listItems; }
        set { _listItems = value; 
            RaisePropertyChanged(() => ListItems);
        }
    }
}

请注意,集合被限制为BaseCellViewModel类型。这使您可以将FirstCustomCellViewModelSecondCustomCellViewModel对象添加到其中:

ListItems = new ObservableCollection<CellViewModelBase>(){
    new FirstCustomCellViewModel(),
    new SecondCustomCellViewModel()
};

现在,您可以像这样在单元格中定义绑定:

protected CustomCell1(IntPtr handle) : base(handle)
{
    this.DelayBind(() =>
    {
        var set = this.CreateBindingSet<CustomCell1, FirstCustomCellViewModel>();
        set.Bind(NameLabel).To(vm => vm.Name);
        set.Apply();
    });
}

protected CustomCell2(IntPtr handle) : base(handle)
{
    this.DelayBind(() =>
    {
        var set = this.CreateBindingSet<CustomCell2, SecondCustomCellViewModel>();
        set.Bind(NameLabel).To(vm => vm.Name); 
        set.Apply();
    });
}

然后在具有UICollectionView的ViewController中,只需绑定源:

var source = new MyCollectionViewSource(MyCollectionView, MyViewModel);
var set = this.CreateBindingSet<MyViewController, ListViewModel>();
set.Bind(source).To(vm => vm.ListItems);
set.Apply();