在MvxCollectionViewCell中的嵌套MvxDialogViewController中获取BindingTarget

时间:2013-06-18 12:40:59

标签: xamarin.ios mvvmcross

我有ViewModel名为LocationsViewModel,其中我有一个ObservableCollection<LocationViewModel>。另外,我有LocationsView MvxCollectionViewController,我在其中创建了一个绑定集并将MvxCollectionViewSource绑定到ObservableCollection

LocationCell MvxCollectionViewCell中,我想显示一个绑定到当前各种属性的MonoTouch.Dialog 选中LocationViewModel。最简单的方法似乎是在MvxDialogViewController中创建一个嵌套的MvxCollectionViewCell,但要绑定它 Elements中的MvxDialogViewController,我显然需要创建一个绑定目标。我的问题是,我是否可以将绑定目标从MvxCollectionViewCell传递到MvxDialogViewController

让我也尝试用一些代码简要解释一下,以提高理解。

LocationsViewModel.cs

public class LocationsViewModel : MvxViewModel
{
    ...
    public ObservableCollection<LocationViewModel> Locations
    {
        get { return _locationDataService.Locations.Locations; }
    }
    ...
}

LocationViewModel.cs

public class LocationViewModel : MvxNotifyPropertyChanged
{
    ...
    //Tons of public properties like:
    public string Name
    {
        get { return LinkedDataModel.Name; }
        set
        {
            LinkedDataModel.Name = value;
            RaisePropertyChanged(() => Name);
        }
    }

    public double CurrentNoiseLevel
    {
        get { return LinkedDataModel.CurrentNoiseLevel; }
        set
        {
            LinkedDataModel.CurrentNoiseLevel = value;
            RaisePropertyChanged(() => CurrentNoiseLevel);
        }
    }
    ...
}

LocationsView.cs

[Register("LocationView")]
public class LocationsView
    : MvxCollectionViewController
{
    static readonly NSString LocationCellId = new NSString("LocationCell");
    private readonly bool _isInitialized;

    public LocationsView()
        : base(new UICollectionViewFlowLayout()
        {
            MinimumInteritemSpacing = 0f,
            ScrollDirection = UICollectionViewScrollDirection.Horizontal,
            MinimumLineSpacing = 0f
        })
    {
        _isInitialized = true;
        ViewDidLoad();
    }

    public new LocationsViewModel ViewModel
    {
        get { return (LocationsViewModel)base.ViewModel; }
        set { base.ViewModel = value; }
    }

    public sealed override void ViewDidLoad()
    {
        if (!_isInitialized)
            return;

        base.ViewDidLoad();

        CollectionView.RegisterClassForCell(typeof(LocationCell), LocationCellId);
        var source = new MvxCollectionViewSource(CollectionView, LocationCellId);
        CollectionView.Source = source;
        CollectionView.PagingEnabled = true;

        var set = this.CreateBindingSet<LocationsView, LocationsViewModel>();
        set.Bind(source).To(vm => vm.Locations);
        set.Apply();

        CollectionView.ReloadData();
    }
}

LocationCell.cs

public class LocationCell : MvxCollectionViewCell
{
    [Export("initWithFrame:")]
    public LocationCell(RectangleF frame)
        : base(string.Empty, frame)
    {
        InitView();
    }

    public LocationCell(IntPtr handle)
        : base(string.Empty, handle)
    {
        InitView();
    }

    private void InitView()
    {
        var cell = new LocationCellDialog();
        ContentView.Add(cell.View);
    }

    public class LocationCellDialog 
        : MvxDialogViewController
    {
        public LocationCellDialog() 
            : base(UITableViewStyle.Grouped, null, true) 
        { }

        public override void ViewDidLoad()
        {
            base.ViewDidLoad();

            //How do I get the target here?
            var target = ??;
            Root = new RootElement
            {
                new Section
                {
                    new StringElement().Bind(target, t => t.Name),
                    new StringElement().Bind(target, t => t.CurrentNoiseLevel)
                }.Bind(target, t => t.Name),
            };
        }
    }
}

所以问题是我可以简单地将绑定目标从父LocationCell传递给嵌套的LocationCellDialog,还是不行?

1 个答案:

答案 0 :(得分:2)

MvvmCross中的每个bindable view都有自己的DataContext

对于顶级View,此DataContextViewModel

对于CellListTable中的CollectionDataContext设置为列表中Cell的对象}目前正在展示。

如果要将Cell中的任何属性数据绑定到DataContext上的属性路径,则可以使用Fluent绑定语法执行此操作。

例如,要将名为Text的子UILabel的{​​{1}}值绑定到列表中myLabel的子属性Name,您可以使用方法:

Person

或者如果您想将 this.CreateBinding(myLabel).For(label => label.Text).To<Person>(p => p.Name).Apply(); 绑定到Text本身,您可以使用:

Person

this.CreateBinding(myLabel).For(label => label.Text).Apply(); 中,我认为您要将嵌套LocationCell的{​​{1}}绑定到包含单元格的DataContext

要做到这一点,你应该可以使用:

LocationCellDialog