2017-09-14 47 views
0

我正在用MvvmCross编写一个Xamarin.iOS应用程序。我试图制作一个表格,我可以看到这些项目被绑定到源代码中,但我从来没有看到任何单元格正在创建。功能GetOrCreateCellFor永远不会被调用。这里是我的代码:UITableViewSource永远不会创建单元格

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; 
    } 
} 

编辑

这是你的源头的工作版本应该是什么样子。另外有趣的是,如果表格没有添加到视图中,GetOrCreateCellFor将不会被调用。

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

实际使用数据项填充集合的支持ViewModel的代码在这里很有用。这听起来像TableView.ReloadData()永远不会被调用。在MvvmCross中 - 这是在对后备集合进行绑定更新时完成的 - 当设置了属性或将项目添加到MvxObservableCollection时删除 – pnavk

+0

我在'ItemsSource'的设置器中调用'ReloadData()'。我只想到了一些事情:它能找到我的FriendCell类吗?我把'[Register(“FriendCell”)]'注释放在类的上面,但也许它正在寻找一个故事板文件呢?我喜欢从后面的代码做我的看法,我不知道如何注册一个类是单元格布局.. – Darius

回答

1

在FriendTableViewSource中重写RowsInSection

由于tableview需要行数和行高来决定其帧,所以如果height = 0或count = 0,则永远不会调用GetOrCreateCellFor

+0

这只是其中一个原因。另外有趣的是,如果表格没有添加到视图中,GetOrCreateCellFor'不会被调用。 – Darius