嵌套列表视图的MvxExpandableTableViewSource

Tun*_*hau 3 xamarin.ios mvvmcross xamarin

我试图在MvvmCross-iOSSupport 4.1中通过MvxExpandableTableViewSource创建一个嵌套的可扩展列表,但它没有希望.请告诉我正确的方法!

Iai*_*ith 6

我尝试使用MvxExpandableTableViewSource但是我在设置_isCollapsedbool数组时遇到了问题.

我知道你必须继承MvxExpandableTableViewSource并确保ItemSource你绑定的是类型,IEnumerable<IEnumerable<object>>但仍然没有任何运气,可能错过了一些东西.

所以我创建了另一种类型的TableViewSource基于, MvxExpandableTableViewSource所以我可以在绑定_isCollapsed时设置bool数组ItemSource,然后我需要绑定到标题为组头部分.这就是我想出的:

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);
}
Run Code Online (Sandbox Code Playgroud)

然后我就这样使用它:

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;
}
Run Code Online (Sandbox Code Playgroud)

还有一些其他位:像标题的单元格和我正在使用的模型.

所以我创建了一个MvvmCross-Samples的分支,并使用分组集合示例修改了"WorkingWithCollection"项目,可在此处找到:

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

看起来像这样:

分组Kittehs !​​!!

希望Grouped Kittehs有所帮助.

UPDATE

这已合并到MvvmCross iOS示例中