Monotouch:重用UITableViewCell的正确方法

Monotouch:重用UITableViewCell的正确方法,uitableview,xamarin.ios,reusability,Uitableview,Xamarin.ios,Reusability,我正在找出在UITableView中重用单元的正确方法,我将知道我使用的机制是否正确 场景如下 我有一个UITableView,它显示从web服务获得的数据列表 _listOfItems = e.Result as List<Item>; 在哪里 _cID是单元的实例变量标识符 string _cID = "MyCellId"; _CellController是一个字典,用于存储项实例的单元格和相对id Dictionary<int, UITableViewCell>

我正在找出在UITableView中重用单元的正确方法,我将知道我使用的机制是否正确

场景如下

我有一个UITableView,它显示从web服务获得的数据列表

_listOfItems = e.Result as List<Item>;
在哪里

_cID是单元的实例变量标识符

string _cID = "MyCellId";
_CellController是一个字典,用于存储项实例的单元格和相对id

Dictionary<int, UITableViewCell> _cellControllers;
Dictionary\u;
我正在使用字典存储单元格,因为当点击一行时,我必须检索被点击单元格的id(通过cell.Tag值),执行一些其他操作,即从服务中检索其他一些数据,然后用新值再次更新该单元格。在这种情况下,每个单元格必须是唯一的

所以,我的问题是:

这是重用单元的正确方式吗?还是有可能找到另一种解决方案来重用单元,并保证单元的每个抽头都是唯一的


我希望一切都清楚:)先谢谢你。问候。

我觉得你在这里做的有点太多了。尤其是在字典中保留对单元格的额外引用的部分

我会换一种方式。DequeueReusableCell方法存在,因此您可以检索任何现有单元格,但不一定检索它包含的值。这样就足够了:

public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath)
{

    int rowIndex = indexPath.Row;
    Item item  = _listOfItems[rowIndex];

    UITableViewCell cell = tableView.DequeueReusableCell(_cID);

    if (cell == null)
    {
        cell = new UITableViewCell(UITableViewCellStyle.Value1, _cID);
    }

    // Store what you want your cell to display always, not only when you are creating it.
    cell.Tag = item.ID;
    cell.TextLabel.Text = item.Title;

    return cell;
}
然后,在RowSelected方法中,更改数据源:

public override void RowSelected (UITableView tableView, NSIndexPath indexPath){
    // Do something here to change your data source _listOfItems[indexPath.Row] = new Item();
}

如果我正确理解了您想要做的事情,这个解决方案会更好。

如果您使用我的MonoTouch.Dialog库,它会为您解决所有这些细节问题,并完全满足您的需要,甚至更多。它将让你专注于你的应用,而不是专注于管理,我相信它将让你行动更快,你可以从以下方面获得:

此代码的第一个问题是将单元格硬编码为单一类型。通常,您必须首先检查节/行,并根据此信息确定所需的单元格类型

确定所需的单元格类型后,使用此信息使用与此单元格ID关联的令牌调用DequeueReusableCell。例如,对于包含入口行的单元格和包含图像的单元格,这是不同的。您需要将正确类型的单元格出列

您不需要使每个单元格都是唯一的,您需要的所有信息都在节/行中,因此您需要的是将节/行映射到唯一单元格的信息。一种简单的方法是,有一个单独的部分,该行是要从中获取更多信息的数据数组的索引

有关创建这些单元格的最佳实践的小教程,请参见:

如果您使用的是MonoTouch.Dialog,那么您的整个代码可能是:

var elements = "foo, bar, baz";
var dvc = new DialogViewController ();
dvc.Root = new RootElement ("My results") {
    from x in elements.Split (',')
        select (Element) new StringElement (x);
};
dvc.Root.Add ("Final one");

current.PresentModalViewController (dvc, true);
上面创建了一个包含4行的UITableView,其中一行使用Linq表示“foo”、“bar”和“baz”,并在末尾添加了一个额外的节点,以演示如何使用Add API


您还可以使用许多分类元素,但不限于字符串元素。

谢谢Dimitris。我认为这可能是一个更好的解决办法。在这种情况下,当您滚动表格时,会从头创建一个单元格或重复使用该单元格,但标记会根据indexpath.row进行更改。不是吗?是的。刚刚编辑了所选方法的行。您甚至不必检索单元格,因为它的标记被设置为项的id。因此您可以直接从列表中的项检索id。我想说的一点是,直接使用数据源,并根据单元格的工作来处理单元格:显示数据,而不是其他任何内容。还有一点:单元格不是从头创建的。该单元创建一次。每次都会根据数据源分配其内容。实际上,您甚至不必指定单元格的标记。
var elements = "foo, bar, baz";
var dvc = new DialogViewController ();
dvc.Root = new RootElement ("My results") {
    from x in elements.Split (',')
        select (Element) new StringElement (x);
};
dvc.Root.Add ("Final one");

current.PresentModalViewController (dvc, true);