2016-04-24 94 views
3

我試圖在MvvmCross-iOSSupport 4.1中通過MvxExpandableTableViewSource製作一個嵌套的可擴展列表,但它沒有希望。請給我看看正確的方法!嵌套列表視圖MvxExpandableTableViewSource

+1

你應該告訴我們你已經嘗試什麼,在哪裏/什麼問題了! –

回答

5

我試圖使用MvxExpandableTableViewSource,但我在設置_isCollapsed bool數組時遇到問題。

我知道你必須子類MvxExpandableTableViewSource並確保你綁定到ItemSourceIEnumerable<IEnumerable<object>>類型,但仍然沒有任何運氣,它可能錯過了一些東西。

因此,我創建基於MvxExpandableTableViewSource所以當ItemSource勢必我可以設置布爾_isCollapsed陣列另一種類型的TableViewSource,然後我需要綁定到標題爲組標頭部分。這是我想出了:

public abstract class MyExpTVS<TItemSource, TItem> : MvxTableViewSource where TItemSource : ItemGroup<TItem> 
{ 
    /// <summary> 
    /// Indicates which sections are expanded. 
    /// </summary> 
    private bool[] _isCollapsed; 

    private IEnumerable<TItemSource> _itemsSource; 
    new public IEnumerable<TItemSource> ItemsSource 
    { 
     get 
     { 
      return _itemsSource; 
     } 
     set 
     { 
      _itemsSource = value; 
      _isCollapsed = new bool[ItemsSource.Count()]; 

      for (var i = 0; i < _isCollapsed.Length; i++) 
       _isCollapsed[i] = true; 
      ReloadTableData(); 
     } 
    } 

    public MyExpTVS(UITableView tableView) : base(tableView) 
    { 
    } 

    protected override void CollectionChangedOnCollectionChanged(object sender, NotifyCollectionChangedEventArgs args) 
    { 
     // When the collection is changed collapse all sections 
     _isCollapsed = new bool[ItemsSource.Count()]; 

     for (var i = 0; i < _isCollapsed.Length; i++) 
      _isCollapsed[i] = true; 

     base.CollectionChangedOnCollectionChanged(sender, args); 
    } 

    public override nint RowsInSection(UITableView tableview, nint section) 
    { 
     // If the section is not colapsed return the rows in that section otherwise return 0 
     if ((ItemsSource?.ElementAt((int)section)).Items.Any() && !_isCollapsed [(int)section]) 
      return (ItemsSource.ElementAt((int)section)).Items.Count(); 
     return 0; 
    } 

    public override nint NumberOfSections(UITableView tableView) 
    { 
     return ItemsSource.Count(); 
    } 

    protected override object GetItemAt(NSIndexPath indexPath) 
    { 
     if (ItemsSource == null) 
      return null; 

     return ItemsSource.ElementAt(indexPath.Section).Items.ElementAt(indexPath.Row); 
    } 

    protected object GetHeaderItemAt(nint section) 
    { 
     if (ItemsSource == null) 
      return null; 

     return ItemsSource.ElementAt((int)section); 
    } 

    public override UIView GetViewForHeader(UITableView tableView, nint section) 
    { 
     var header = GetOrCreateHeaderCellFor(tableView, section); 

     // Create a button to make the header clickable 
     UIButton hiddenButton = new UIButton(header.Frame); 
     hiddenButton.TouchUpInside += EventHandler(tableView, section); 
     header.AddSubview(hiddenButton); 

     // Set the header data context 
     var bindable = header as IMvxDataConsumer; 
     if (bindable != null) 
      bindable.DataContext = GetHeaderItemAt(section); 
     return header; 
    } 

    private EventHandler EventHandler(UITableView tableView, nint section) 
    { 
     return (sender, e) => 
     { 
      // Toggle the is collapsed 
      _isCollapsed[(int)section] = !_isCollapsed[(int)section]; 
      tableView.ReloadData(); 

      // Animate the section cells 
      var paths = new NSIndexPath[RowsInSection(tableView, section)]; 
      for (int i = 0; i < paths.Length; i++) 
      { 
       paths[i] = NSIndexPath.FromItemSection(i, section); 
      } 

      tableView.ReloadRows(paths, UITableViewRowAnimation.Automatic); 
     }; 
    } 

    public override void HeaderViewDisplayingEnded(UITableView tableView, UIView headerView, nint section) 
    { 
     var bindable = headerView as IMvxDataConsumer; 
     if (bindable != null) 
      bindable.DataContext = null; 
    } 

    /// <summary> 
    /// This is needed to show the header view. Should be overriden by sources that inherit from this. 
    /// </summary> 
    /// <param name="tableView"></param> 
    /// <param name="section"></param> 
    /// <returns></returns> 
    public override nfloat GetHeightForHeader(UITableView tableView, nint section) 
    { 
     return 44; // Default value. 
    } 

    public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath) 
    { 
     return base.GetCell(tableView, indexPath); 
    } 

    /// <summary> 
    /// Gets the cell used for the header 
    /// </summary> 
    /// <param name="tableView"></param> 
    /// <param name="section"></param> 
    /// <returns></returns> 
    protected abstract UITableViewCell GetOrCreateHeaderCellFor(UITableView tableView, nint section); 

    protected abstract override UITableViewCell GetOrCreateCellFor(UITableView tableView, NSIndexPath indexPath, object item); 
} 

然後我用它像這樣:

public class BaseGroupedTableView : MvxTableViewController 
{ 
    public override void ViewDidLoad() 
    { 
     base.ViewDidLoad(); 

     var source = new GroupTableSource(TableView) 
     { 
      UseAnimations = true, 
      AddAnimation = UITableViewRowAnimation.Left, 
      RemoveAnimation = UITableViewRowAnimation.Right 
     }; 

     this.AddBindings(new Dictionary<object, string> 
      { 
       {source, "ItemsSource Kittens"} 
      }); 

     TableView.Source = source; 
     TableView.ReloadData(); 
    } 
} 

public class GroupTableSource : MyExpTVS<KittenType, Kitten> 
{ 
    public GroupTableSource(UITableView tableView) : base(tableView) 
    { 
     string nibName = "KittenCell"; 
     this._cellIdentifier = new NSString(nibName); 
     tableView.RegisterNibForCellReuse(UINib.FromName(nibName, NSBundle.MainBundle), CellIdentifier); 


     string nibName2 = "HeaderCell"; 
     this._headerCellIdentifier = new NSString(nibName2); 
     tableView.RegisterNibForCellReuse(UINib.FromName(nibName2, NSBundle.MainBundle), HeaderCellIdentifier); 
    } 

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


    protected override UITableViewCell GetOrCreateHeaderCellFor(UITableView tableView, nint section) 
    { 
     return tableView.DequeueReusableCell(this.HeaderCellIdentifier); 
    } 

    protected override UITableViewCell GetOrCreateCellFor(UITableView tableView, NSIndexPath indexPath, object item) 
    { 
     return tableView.DequeueReusableCell(this.CellIdentifier); 
    } 

    private readonly NSString _cellIdentifier; 
    protected virtual NSString CellIdentifier => this._cellIdentifier; 

    private readonly NSString _headerCellIdentifier; 
    protected virtual NSString HeaderCellIdentifier => this._headerCellIdentifier; 
} 

還有一些其他位:像頭細胞和我所用的模型。

所以我創建了MvvmCross樣本的一個分支和變化的一個分組集合例如「WorkingWithCollection」項目可以在這裏找到:

https://github.com/b099l3/MvvmCross-Samples/tree/master/WorkingWithCollections

,看起來像這樣:

Grouped Kittehs!!!

希望分組的Kittehs幫助。

UPDATE

這被合併到MvvmCross iOS samples here

+0

這很好,謝謝。爲kitteh gif +1! –