实现 TreeModel 非常尴尬/困难,因此大多数人只是将数据从他们的“真实”模型同步到 TreeStore 或 ListStore。
商店中的列不必以任何方式与视图中的列匹配。例如,您可以拥有一个包含真实托管数据对象的列。
当您将 cellrenderer 添加到 TreeView(可视)列时,您可以在其属性和商店的列之间添加映射。例如,您可以将一个存储列映射到文本单元渲染器的字体,并将另一个存储列映射到同一单元渲染器的文本属性。每次使用 cellrenderer 渲染特定单元格时,映射将用于从存储中检索值,并在渲染之前将它们应用于渲染器的属性。
下面是一个映射示例:
treeView.AppendColumn ("Title", renderer, "text", 0, "editable", 4);
这会将存储列 0 映射到渲染器的text
GTK 属性,并将存储列 4 映射到editable
属性。对于 GTK 属性名称,您可以查看GTK 文档。请注意,上面的示例使用了一种方便的方法,它添加了一个列,向它添加了一个渲染器,并通过参数添加了任意数量的映射。要将映射直接添加到列,例如具有多个渲染器的列,请将渲染器打包到列中,然后使用TreeViewColumn.AddAttribute
or TreeViewColumn.SetAttributes
。
您还可以设置将用于代替映射的自定义数据函数。这允许您直接设置渲染器的属性,给定 TreeIter 和存储 - 因此,如果您要显示的所有数据都是从您的真实数据对象中派生出来的,您甚至可以让您的存储仅包含一列这些对象,并为所有视图列使用数据函数。
下面是一个数据函数的例子,它与上面的映射例子完全一样:
treeColumn.SetCellDataFunc (renderer, delegate (TreeViewColumn col,
CellRenderer cell, TreeModel model, TreeIter iter)
{
var textCell = (CellRendererText) cell;
textCell.Text = (string) model.GetValue (iter, 0);
textCell.Editable = (bool) model.GetValue (iter, 4);
});
显然,数据函数要强大得多,因为它们不仅使您能够使用更复杂的 GTK 对象的属性,而且还可以实现更复杂的显示逻辑——例如,仅在实际渲染单元格时才延迟处理派生值。