2017-09-14 8 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; 
    } 
} 

EDIT

これはあなたの元の作業バージョンがどのように見えるかです。興味深いのは、テーブルがビューに追加されていない場合、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を上書きします。

テーブルビューでは、フレームを決定するために行数と行の高さが必要なので、height = 0またはcount = 0の場合、GetOrCreateCellForは決して呼び出されません。

+0

これは単なる理由の1つでした。興味深いのは、テーブルがビューに追加されていない場合、 'GetOrCreateCellFor'は呼び出されないということです。 – Darius

関連する問題