5

我正在使用带有 ListStore 作为模型的 TreeView。当用户单击一行时,我想采取一些行动,但不使用单元格中的值,而是使用我创建该行的数据......

目前我有 TreeView、TreeModel (ListStore) 和我自己的数据(我讽刺地称之为模型)..

所以问题是:

拥有一个模型是否“正确” - 我要显示的数据的对象表示并用该数据填充 ListStore 以显示在 TreeView 中,或者最好实现自己的 TreeModel 版本(包装我的数据 -模型)来显示数据?

并且:

如果有人连续双击,我可以获得 RowActivated 事件(使用 C#/Gtk#),它提供了激活行的路径。有了它,我可以获得一个 TreeIter 并使用它可以获得一个单元格的值。但是,首先找到构建行的数据对象的最佳实践是什么?\(不知何故,这个问题让我想到了第一个问题 - 如果我尝试实现自己的数据对象会更容易获得树模型...)

4

1 回答 1

7

实现 TreeModel 非常尴尬/困难,因此大多数人只是将数据从他们的“真实”模型同步到 TreeStore 或 ListStore。

商店中的列不必以任何方式与视图中的列匹配。例如,您可以拥有一个包含真实托管数据对象的列。

当您将 cellrenderer 添加到 TreeView(可视)列时,您可以在其属性和商店的列之间添加映射。例如,您可以将一个存储列映射到文本单元渲染器的字体,并将另一个存储列映射到同一单元渲染器的文本属性。每次使用 cellrenderer 渲染特定单元格时,映射将用于从存储中检索值,并在渲染之前将它们应用于渲染器的属性。

下面是一个映射示例:

treeView.AppendColumn ("Title", renderer, "text", 0, "editable", 4);

这会将存储列 0 映射到渲染器的textGTK 属性,并将存储列 4 映射到editable属性。对于 GTK 属性名称,您可以查看GTK 文档。请注意,上面的示例使用了一种方便的方法,它添加了一个列,向它添加了一个渲染器,并通过参数添加了任意数量的映射。要将映射直接添加到列,例如具有多个渲染器的列,请将渲染器打包到列中,然后使用TreeViewColumn.AddAttributeor 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 对象的属性,而且还可以实现更复杂的显示逻辑——例如,仅在实际渲染单元格时才延迟处理派生值。

于 2010-12-22T18:56:44.393 回答