如何正确使用GtkTreeView

Nil*_*ils 5 gtk mono gtk# gtktreeview

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

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

所以问题是:

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

并且:

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

Mik*_*son 7

实现TreeModel非常笨拙/困难,因此大多数人只是将数据从"真实"模型同步到TreeStore或ListStore.

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

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

这是一个映射的例子:

treeView.AppendColumn ("Title", renderer, "text", 0, "editable", 4);
Run Code Online (Sandbox Code Playgroud)

这会将存储列0映射到渲染器的textGTK属性,并将存储列4映射到该editable属性.对于GTK属性名称,您可以检查GTK文档.请注意,上面的示例使用了一种方便的方法,即添加列,向其添加渲染器并通过参数添加任意数量的映射.要将映射直接添加到列(例如,具有多个渲染器的列),请将渲染器打包到列中,然后使用TreeViewColumn.AddAttributeTreeViewColumn.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);
});
Run Code Online (Sandbox Code Playgroud)

显然,数据函数功能更强大,因为它们不仅可以使用更复杂的GTK对象的属性,还可以实现更复杂的显示逻辑 - 例如,只有在实际渲染单元格时才会延迟处理派生值.