Mvvmcross MvxSimpleTableViewSource绑定

3
我正在尝试创建自定义单元格用于我的MvxTableViewController,就像Stuart Lodge在N=3和N=6.5视频中所展示的那样,但它无法绑定数据。
这里是工作版本(基本单元格的版本)。
using Cirrious.MvvmCross.Binding.BindingContext;
using Cirrious.MvvmCross.Binding.Touch.Views;
using Cirrious.MvvmCross.Touch.Views;
using Cirrious.MvvmCross.ViewModels;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
using Next.Client.Application.Core.Entities.Observations;
using Next.Client.Application.Core.ViewModels;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;

namespace Next.Client.Application.iOS.Views
{
    [Register("ObsSearchView")]
    public partial class ObsSearchView : MvxTableViewController
    {
        public static readonly NSString CellIdentifier = new NSString("ObservationCell");

        public ObsSearchView()
        {
        }

        public ObsSearchView(IntPtr handle)
            : base(handle)
        {
        }

        public override void ViewDidLoad()
        {
            base.ViewDidLoad();
            Request = new MvxViewModelRequest<ObsSearchViewModel>(null, null, new MvxRequestedBy());
            LoadData();
        }

        public override void ViewWillAppear(bool animated)
        {
            base.ViewWillAppear(animated);
            Title = NSBundle.MainBundle.LocalizedString("Liste Observations", "Liste Observations");
        }

        public override void ViewWillDisappear(bool animated)
        {
            Title = NSBundle.MainBundle.LocalizedString("Back", "Liste Observations");
            base.ViewDidDisappear(animated);
        }

        public void LoadData()
        {                
            var source = new MvxStandardTableViewSource(
                TableView,
                UITableViewCellStyle.Subtitle,
                CellIdentifier,
                "TitleText BrutText; DetailText DateTimeHuman",
                UITableViewCellAccessory.DisclosureIndicator
            );

            TableView.Source = source;

            var set = this.CreateBindingSet<ObsSearchView, Core.ViewModels.ObsSearchViewModel>();

            set.Bind(source).To(vm => vm.Observations);
            set.Bind(source).For(s => s.SelectionChangedCommand).To(vm => vm.SelectedObsCommand);
            set.Apply();

            TableView.ReloadData();
        }
    }
}

这里是添加自定义单元格的修改版本:

using Cirrious.MvvmCross.Binding.BindingContext;
using Cirrious.MvvmCross.Binding.Touch.Views;
using Cirrious.MvvmCross.Touch.Views;
using Cirrious.MvvmCross.ViewModels;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
using Next.Client.Application.Core.Entities.Observations;
using Next.Client.Application.Core.ViewModels;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;

namespace Next.Client.Application.iOS.Views
{
    [Register("ObsSearchView")]
    public partial class ObsSearchView : MvxTableViewController
    {
        public static readonly NSString CellIdentifier = new NSString("ObservationCell");

        public ObsSearchView()
        {
        }

        public ObsSearchView(IntPtr handle)
            : base(handle)
        {
        }

        public override void ViewDidLoad()
        {
            base.ViewDidLoad();
            Request = new MvxViewModelRequest<ObsSearchViewModel>(null, null, new MvxRequestedBy());
            LoadData();
        }

        public override void ViewWillAppear(bool animated)
        {
            base.ViewWillAppear(animated);
            Title = NSBundle.MainBundle.LocalizedString("Liste Observations", "Liste Observations");
        }

        public override void ViewWillDisappear(bool animated)
        {
            Title = NSBundle.MainBundle.LocalizedString("Back", "Liste Observations");
            base.ViewDidDisappear(animated);
        }

        public void LoadData()
        {
            var source = new MvxSimpleTableViewSource(
                TableView, 
                ObservationCell.Key,
                ObservationCell.Key
            );
            TableView.Source = source;

            TableView.ReloadData();
        }
    }
}

使用自定义单元格类
using System;
using System.Drawing;
using MonoTouch.Foundation;
using MonoTouch.UIKit;
using Cirrious.MvvmCross.Binding.Touch.Views;
using Cirrious.MvvmCross.Binding.BindingContext;
using Next.Client.Application.Core.ViewModels;
using Next.Client.Application.Core.Entities.Observations;

namespace Next.Client.Application.iOS
{
    public partial class ObservationCell : MvxTableViewCell
    {
        public static readonly UINib Nib = UINib.FromName ("ObservationCell", NSBundle.MainBundle);
        public static readonly NSString Key = new NSString ("ObservationCell");

        public ObservationCell (IntPtr handle) : base (handle)
        {
            this.DelayBind(() => {
                var set = this.CreateBindingSet<ObservationCell, Observation>();
                set.Bind(MainLbl).To(observation => observation.BrutText);
                set.Bind(SubLeftLbl).To(observation => observation.DateTimeHuman);
                set.Bind(SubRightLbl).To(observation => observation.Praticien.Personne.DisplayFullName);
                set.Apply();
            });
        }

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

最后是观察实体(Observation entity)

using Next.Client.Application.Core.Helpers;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using Next.Client.Application.Core.Entities;
using System.Globalization;

namespace Next.Client.Application.Core.Entities.Observations
{
    public class Observation : Entity
    {
        #region Constructors
        #endregion

        #region Constantes
        private readonly List<String> _month = new List<String>{
                "",
                "jan.",
                "fev.",
                "mars",
                "avr.",
                "mai",
                "juin",
                "jui.",
                "aout",
                "sep.",
                "oct.",
                "nov.",
                "dec."
            };
        #endregion


        #region Simple Properties

        #region Foreign keys

        private int _praticienId;
        public int PraticienId
        {
            get { return _praticienId; }
            set { _praticienId = value; OnPropertyChange(() => PraticienId); }
        }

        private int _sejourId;
        public int SejourId
        {
            get { return _sejourId; }
            set { _sejourId = value; OnPropertyChange(() => SejourId); }
        }

        private int _categoryId;
        public int CategoryId
        {
            get { return _categoryId; }
            set { _categoryId = value; OnPropertyChange(() => CategoryId); }
        }
        #endregion

        private DateTime _dateTime;
        public DateTime DateTime
        {
            get { return _dateTime; }
            set { _dateTime = value; OnPropertyChange(() => DateTime); OnPropertyChange(() => DateTimeHuman); }
        }

        public String DateTimeHuman
        {
            get
            {
                CultureInfo culture = new CultureInfo("fr-FR");
                return DateTime.ToString("f", culture);
            }
        }

        public string DisplayDateTime
        {
            get { return string.Format("{0} {1} {2} {3}h{4:00}", _dateTime.Day, _month[_dateTime.Month], _dateTime.Year, _dateTime.Hour, _dateTime.Minute); }
        }
        private int _status;
        public int Status
        {
            get { return _status; }
            set { _status = value; OnPropertyChange(() => Status); }
        }

        private int _type;
        public int Type
        {
            get { return _type; }
            set { _type = value; OnPropertyChange(() => Type); }
        }

        private bool _private;
        public bool Private
        {
            get { return _private; }
            set { _private = value; OnPropertyChange(() => Private); OnPropertyChange(() => DisplayPrivacy); }
        }

        public string DisplayPrivacy
        {
            get { if (_private) return "OUI"; else return "NON"; }
        }

        private string _brutText;
        public string BrutText
        {
            get { return _brutText; }
            set { _brutText = value; OnPropertyChange(() => BrutText); }
        }

        #endregion

        #region Navigation Properties

        private Praticien _praticien;
        public Praticien Praticien
        {
            get { return _praticien; }
            set
            {
                Praticien old = _praticien;
                _praticien = value;
                CollectionHelper.ManyToOne(this, old, value, _GetManyToOneCollection);
                OnPropertyChange(() => Praticien);
            }
        }

        private Sejour _sejour;
        public Sejour Sejour
        {
            get { return _sejour; }
            set
            {
                Sejour old = _sejour;
                _sejour = value;
                CollectionHelper.ManyToOne(this, old, value, _GetManyToOneCollection);
                OnPropertyChange(() => Sejour);
            }
        }

        private Category _category;
        public Category Category
        {
            get { return _category; }
            set
            {
                Category old = _category;
                _category = value;
                CollectionHelper.ManyToOne(this, old, value, _GetManyToOneCollection);
                OnPropertyChange(() => Category);
            }
        }

        private ObservableCollection<BinaryObservation> _datas;
        public ObservableCollection<BinaryObservation> Datas
        {
            get
            {
                if (_datas == null)
                {
                    _datas = new ObservableCollection<BinaryObservation>();
                    CollectionHelper.OneToMany(this, _GetOneToMany, _SetOneToMany, _datas);

                }
                return _datas;
            }
            set { _datas = value; OnPropertyChange(() => Datas); }
        }

        #endregion

        #region Association Fixup

        private static ObservableCollection<Observation> _GetManyToOneCollection(Sejour sejour)
        {
            return sejour.Observations;
        }

        private static ObservableCollection<Observation> _GetManyToOneCollection(Category category)
        {
            return category.Observations;
        }

        private static ObservableCollection<Observation> _GetManyToOneCollection(Praticien praticien)
        {
            return praticien.Observations;
        }

        #region binary observation (datas)

        private static Observation _GetOneToMany(BinaryObservation binaryObservation)
        {
            return binaryObservation.Observation;
        }

        private static void _SetOneToMany(BinaryObservation binaryObservation, Observation observation)
        {
            binaryObservation.Observation = observation;
        }

        #endregion
        #endregion

    }
}

当我构建时,没有错误,并且我可以运行调试器而不出错,但是当使用自定义单元格时,没有任何东西显示出来,因此似乎绑定方式不正确。
感谢您的时间。

我需要从列表中获取选定的项目,因此我绑定了源SelectedItem属性,但每次都返回Null。我写的代码如下:set.Bind(source).For(P => P.SelectedItem).To(vm => vm.SelectedOrganization); 如果这样不对,请告诉我如何获取选定的项目? - Ajay Sharma
1个回答

1
在您修改的ObsView中,您从未实际绑定TableSource的ItemsSource-因此,表源不知道要显示哪个集合。
在N+1 3 Kittens教程中,使用以下方法完成:
        var set = this.CreateBindingSet<FirstView, FirstViewModel>();
        set.Bind(source).To(vm => vm.Kittens);
        set.Apply();

请看https://github.com/MvvmCross/NPlus1DaysOfMvvmCross/blob/master/N-03-KittenView_Mac/KittenView.Touch/Views/FirstView.cs#L24

同样地,在N=6:

        var set = this.CreateBindingSet<FirstView, Core.ViewModels.FirstViewModel>();
        // ...
        set.Bind(source).To(vm => vm.Results);
        // ...
        set.Apply();

请查看https://github.com/MvvmCross/NPlus1DaysOfMvvmCross/blob/master/N-07-BooksPlus/Books.Touch/Views/FirstView.cs#L45


太好了!我错过了基本绑定 :) 这真的是初学者犯的错误。非常感谢你的答案(顺便说一下,你的视频对于 mvvmcross 的新手来说真是很有帮助;) ) - kitensei
我需要从列表中获取选定的项目,因此我绑定了源SelectedItem属性,但每次都返回Null。我写的代码如下: set.Bind(source).For(P => P.SelectedItem).To(vm => vm.SelectedOrganization); 如果这样不对,请告诉我如何获取选定的项目? - Ajay Sharma

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接