2017-09-14 4 views
0

J'écris une application Xamarin.iOS avec MvvmCross. J'essaie de faire une table, je peux voir les éléments étant liés à la source, mais je ne vois jamais de cellules créées. La fonction GetOrCreateCellFor n'est jamais appelée. Voici mon code:UITableViewSource ne crée jamais de cellules

public class ContactsManager 
{ 
    ContactsView _contactsView; 

    public ContactsManager() 
    { 
     _contactsView = new ContactsView(); 
     Source = new FriendTableViewSource(_contactsView.FriendsTableView); 
     _contactsView.FriendsTableView.Source = Source; 
    } 

    public FriendTableViewSource Source { get; set; } 
} 

public class FriendTableViewSource : MvxTableViewSource 
{ 
    private readonly List<SeeMyFriendsItemViewModel> _content = new List<SeeMyFriendsItemViewModel>(); 
    private readonly UITableView _tableView; 

    public FriendTableViewSource(UITableView t) : base(t) 
    { 
     _tableView = t; 
     t.RegisterNibForCellReuse(UINib.FromName(FriendCell.Key, NSBundle.MainBundle), FriendCell.Key); 
    } 

    private void Init(IEnumerable<SeeMyFriendsItemViewModel> items) 
    { 
     _content.Clear(); 
     _content.AddRange(items); 
    } 

    public override System.Collections.IEnumerable ItemsSource 
    { 
     get 
     { 
      return base.ItemsSource; 
     } 
     set 
     { 
      // I put a break point here to check if I'm getting the items, and it is, so the binding is fine... 
      if (value != null) 
       Init(value.Cast<SeeMyFriendsItemViewModel>()); 
      base.ItemsSource = value; 

      _tableView.ReloadData(); 
     } 
    } 

    public override nfloat GetHeightForRow(UITableView tableView, NSIndexPath indexPath) 
    { 
     return 60; 
    } 

    protected override UITableViewCell GetOrCreateCellFor(UITableView tableView, NSIndexPath indexPath, object item) 
    { 
     // This function never gets called! 
     return TableView.DequeueReusableCell(FriendCell.Key, indexPath); 
    } 
} 

[Register("FriendCell")] 
public class FriendCell : MvxTableViewCell 
{ 
    public static readonly NSString Key = new NSString("FriendCell"); 
    public static readonly UINib Nib; 

    static FriendCell() 
    { 
     Nib = UINib.FromName("FriendCell", NSBundle.MainBundle); 
    } 

    protected FriendCell(IntPtr handle) : base(handle) 
    { 
     BackgroundColor = UIColor.Red; 
    } 
} 

EDIT

C'est ce que une version de travail de votre source devrait ressembler. Ce qui est également intéressant est que GetOrCreateCellFor ne sera pas appelé si la table n'est pas ajoutée à votre vue.

public class FriendTableViewSource : MvxTableViewSource 
{ 
    private readonly List<SeeMyFriendsItemViewModel> _content = new List<SeeMyFriendsItemViewModel>(); 
    private MvxNotifyCollectionChangedEventSubscription _subscription; 

    public FriendTableViewSource(UITableView t) : base(t) 
    { 
     t.RegisterClassForCellReuse(typeof(FriendCell), FriendCell.Key); 
    } 

    private void Init(IEnumerable<SeeMyFriendsItemViewModel> items) 
    { 
     _content.Clear(); 
     _content.AddRange(items); 
    } 

    public override System.Collections.IEnumerable ItemsSource 
    { 
     get 
     { 
      return base.ItemsSource; 
     } 
     set 
     { 
      if (value != null) 
      { 
       Init(value.Cast<SeeMyFriendsItemViewModel>()); 

       var collectionChanged = value as System.Collections.Specialized.INotifyCollectionChanged; 
       if (collectionChanged != null) 
       { 
        _subscription = collectionChanged.WeakSubscribe(CollectionChangedOnCollectionChanged); 
       } 
      } 
      base.ItemsSource = value; 

      ReloadTableData(); 
     } 
    } 

    protected override void CollectionChangedOnCollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs args) 
    { 
     if (args.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add) 
     { 
      foreach (var item in args.NewItems) 
      { 
       var chatItem = item as SeeMyFriendsItemViewModel; 
       _content.Add(chatItem); 
      } 
     } 

     Init(ItemsSource.Cast<SeeMyFriendsItemViewModel>()); 
     base.CollectionChangedOnCollectionChanged(sender, args); 

     InvokeOnMainThread(() => { 
      ReloadTableData(); 

      TableView.SetContentOffset(new CGPoint(0, TableView.ContentSize.Height - TableView.Frame.Size.Height), true); 
     }); 
    } 

    public override nfloat GetHeightForRow(UITableView tableView, NSIndexPath indexPath) 
    { 
     return 60; 
    } 

    public override nint RowsInSection(UITableView tableview, nint section) 
    { 
     return _content.Count(); 
    } 

    public override nint NumberOfSections(UITableView tableView) 
    { 
     return 1; 
    } 

    protected override object GetItemAt(NSIndexPath indexPath) 
    { 
     if (indexPath.Row < _content.Count) 
      return _content[indexPath.Row]; 

     return null; 
    } 

    protected override UITableViewCell GetOrCreateCellFor(UITableView tableView, NSIndexPath indexPath, object item) 
    { 
     return TableView.DequeueReusableCell(FriendCell.Key, indexPath); 
    } 
} 
+0

Le code du ViewModel de support qui remplit réellement la collection avec des éléments de données serait utile ici. Cela ressemble à TableView.ReloadData() n'est jamais appelé. Dans MvvmCross - ceci est fait quand il y a une mise à jour de liaison à la collection de sauvegarde - quand la propriété est définie ou des éléments sont ajoutés/retirés d'un MvxObservableCollection – pnavk

+0

J'appelle 'ReloadData()' dans le setter de 'ItemsSource'. Et j'ai juste pensé à quelque chose: sera-t-il capable de trouver ma classe 'FriendCell'? Je mets l'annotation '[Register (" FriendCell ")]' au-dessus de la classe, mais peut-être cherche-t-elle plutôt un fichier storyboard? J'aime faire mon point de vue du code derrière et je ne suis pas sûr comment enregistrer une classe pour être la disposition de la cellule .. – Darius

Répondre

1

Remplacer RowsInSection dans FriendTableViewSource.

Étant donné que tableview a besoin du nombre de lignes et de la hauteur de ligne pour décider de sa trame, si height = 0 ou count = 0, GetOrCreateCellFor ne sera jamais appelée.

+0

Ce n'était qu'une des raisons. Ce qui est également intéressant, c'est que 'GetOrCreateCellFor' ne sera pas appelé si la table n'est pas ajoutée à votre vue. – Darius