Reputation: 2530
I'm trying to create custom cells for my MvxTableViewController as showed in Stuart Lodge videos N=3 & N=6.5 but it fails to bind data.
Here the working version (the one with basic cells)
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();
}
}
}
and here the modified version to add custom cells:
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();
}
}
}
with the custom cell class
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];
}
}
}
and finally the 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
}
}
when I build I get no error and I can run the debugger without errors either, but when using the custom cells nothing show up, so it seems the binding isn't done the right way.
Thanks for your time
Upvotes: 3
Views: 4900
Reputation: 66882
In your modified ObsView you are never actually binding the ItemsSource
for TableSource - so the table source doesn't know what collection to show
In the N+1 3 Kittens tutorial this is done using:
var set = this.CreateBindingSet<FirstView, FirstViewModel>();
set.Bind(source).To(vm => vm.Kittens);
set.Apply();
Similarly, in N=6:
var set = this.CreateBindingSet<FirstView, Core.ViewModels.FirstViewModel>();
// ...
set.Bind(source).To(vm => vm.Results);
// ...
set.Apply();
Upvotes: 1