【问题标题】:Unable to bind to ios table section cells in mvvmcross, child cells bind as expected无法绑定到 mvvmcross 中的 ios 表格部分单元格,子单元格按预期绑定
【发布时间】:2014-07-17 14:57:16
【问题描述】:

我正在尝试创建一个包含如下分组部分的 TableView:

我正在将一组组列表绑定到表。一个组包含一些字符串属性和一个项目列表,而一个项目也包含一些字符串属性。 group 和 item 单元都有自己的类,扩展 MvxTableViewCell

在我绑定的每个单元格的类中如下:

项目单元格:

 this.DelayBind(() =>
                {
                    var set = this.CreateBindingSet<ItemCellView, ItemCellViewModel>();
                    set.Bind(lblOne).To(item=> item.propertyOne);
                    set.Apply();
                });

还有组格:

this.DelayBind(() =>
                    {
                        var set = this.CreateBindingSet<GroupCellView, GroupCellViewModel>();
                        set.Bind(lblOne).To(group=> group.propertyOne);
                        set.Apply();
                    });

主视图中的我的 TableSource 扩展了 MvxStandardTableViewSource 并使用重写的方法来获取表格的相应单元格。 public override UIView GetViewForHeader 返回一个组单元格视图,而protected override UITableViewCell GetOrCreateCellFor 返回一个项目单元格视图。

我的问题是组视图单元格没有绑定,而项目视图单元格绑定得很好,即使我看不出两者之间有明显的区别。然而,组视图单元正在构建中,它只是在单元内部没有发生的绑定。

编辑:添加表格视图源:

private class TableSource : MvxStandardTableViewSource
        {
            private List<GroupCellViewModel> _groups;
            public new List<GroupCellViewModel> ItemsSource
            {
                get
                {
                    return _groups;
                }
                set
                {
                    _groups = value;
                    ReloadTableData();
                }
            }

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

            public override string TitleForHeader(UITableView tableView, int group)
            {
                if (_groups == null)
                    return string.Empty;

                return Utils.FormatDate(_groups[group].Date);
            }

            public override UIView GetViewForHeader(UITableView tableView, int group)
            {
                return MakeHeaderRow(tableView, _groups[group]);
            }

            public override float GetHeightForHeader(UITableView tableView, int section)
            {
                return 50;
            }

            public override float GetHeightForRow(UITableView tableView, NSIndexPath indexPath)
            {
                return 50;
            }

            public override int NumberOfSections(UITableView tableView)
            {
                if (_groups == null)
                    return 0;

                return _groups.Count;
            }

            public override int RowsInSection(UITableView tableview, int group)
            {
                if (_groups == null)
                    return 0;

                return _groups[group].Items.Count;
            }

            protected override UITableViewCell GetOrCreateCellFor(UITableView tableView, NSIndexPath indexPath, object item)
            {
                UITableViewCell cell;
                if (item is Item)
                {
                    cell = MakeItemRow(tableView, (Item)item);
                }
                else
                {
                    throw new ArgumentException("Unknown cell type " + item.GetType().Name);
                }

                return cell;
            }

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

                return _groups[indexPath.Section].Items[indexPath.Row];
            }

            private UITableViewCell MakeHeaderRow(UITableView tableView, GroupCellViewModel group)
            {
                var existing = (GroupCellView)tableView.DequeueReusableCell(GroupCellView.Key);
                if (existing != null)
                    return existing;

                return new GroupCellView();
            }

            private UITableViewCell MakeItemRow(UITableView tableView, Item item)
            {
                var existing = (ItemCellView)tableView.DequeueReusableCell(ItemCellView.Key);
                if (existing != null)
                    return existing;

                return new ItemCellView();
            }
        }

【问题讨论】:

  • 你也可以发布你的 TableViewSource 吗?
  • @Cheesebaron 刚刚修改了帖子并添加了它

标签: c# ios xamarin mvvmcross


【解决方案1】:

我认为您的解决方案几乎就在那里 - 但您需要提供一个 GetViewForHeader 实现,它有点像 MvvmCross 提供的绑定 GetCell 实现 - 请注意 DataContext 中的设置:

    public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
    {
        var item = GetItemAt(indexPath);
        var cell = GetOrCreateCellFor(tableView, indexPath, item);

        var bindable = cell as IMvxDataConsumer;
        if (bindable != null)
            bindable.DataContext = item;

        return cell;
    }

来自https://github.com/MvvmCross/MvvmCross/blob/v3.1/Cirrious/Cirrious.MvvmCross.Binding.Touch/Views/MvxBaseTableViewSource.cs#L97

对于标题,您需要将DataContext 设置为组标题的适当“视图模型”。

【讨论】:

  • 谢谢,这成功了。我很好奇为什么必须为标题行而不是常规行手动设置数据上下文?