2017-09-14 3 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'의 setter에서'ReloadData()'를 호출합니다. 방금 뭔가 생각했습니다. 내 'FriendCell'클래스를 찾을 수 있습니까? 나는 클래스 위에 주석 등록 ("FriendCell")] 주석을 달았지만 스토리 보드 파일을 대신 찾고있을 수도있다. 뒤에있는 코드에서 내 견해를하고 싶습니다. 클래스를 셀 레이아웃으로 등록하는 방법을 잘 모릅니다. – Darius

답변

1

FriendTableViewSource에서 RowsInSection을 덮어 씁니다.

프레임을 결정하기 위해 tableview에 행 수와 행 높이가 있어야하므로 height = 0 또는 count = 0이면 GetOrCreateCellFor이 호출되지 않습니다.

+0

이것은 이유 중 하나였습니다. 흥미로운 점은 테이블이 뷰에 추가되지 않으면'GetOrCreateCellFor'가 호출되지 않는다는 것입니다. – Darius

관련 문제