如何正确使用GtkTreeView

发布于 2024-10-08 12:36:22 字数 473 浏览 8 评论 0原文

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

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

所以问题是:

拥有一个模型(我想要显示的数据的对象表示形式并用该数据填充 ListStore 以在 TreeView 中显示)是“正确的”吗?更好地实现自己的 TreeModel 版本(包装我的数据模型)来显示数据?

另外:

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

I am using a TreeView with a ListStore as model. When the user clicks on a row I want to take some action but not using the values in the cells, but using the data I created the row from...

Currently I have the TreeView, the TreeModel (ListStore) and my own data (which I ironically call model)..

So the Questions are:

Is it "right" to have a model - an object representation of the data I want to display and fill a ListStore with that data to display in a TreeView, or would it be better to implement an own version of TreeModel (wrapping my data-model) to display the data?

And also:

If someone double-clicks in a row I can get the RowActivated event (using C#/Gtk#) which provides a Path to the activated row. With that I can get a TreeIter and using that I can get the value of a cell. But what is the best practice to find the data object from which the row was constructed in the first place?\
(Somehow this question got me to the first one - by thinking would getting the data object more easy if I tried to implement my own TreeModel...)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦在深巷 2024-10-15 12:36:22

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

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

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

下面是一个映射示例:

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

它将存储列 0 映射到渲染器的 text GTK 属性,并将存储列 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);
});

显然,数据函数更加强大,因为它们不仅使您能够使用更复杂的 GTK 对象的属性,而且还能够实现更复杂的显示逻辑 - 例如,仅在实际渲染单元格时延迟处理派生值。

It's quite awkward/difficult to implement TreeModel, so most people simply synch the data from their "real" model into a TreeStore or ListStore.

The columns in the store do not have to match the columns in the view in any way. For example, you can have a column that contains your real managed data objects.

When you add a cellrenderer to a TreeView (visual) column, you can add mappings between its properties and the columns of the store. For example, you could map one store column to the font of a text cellrenderer, and another store column to the text property of the same cellrenderer. Each time the cellrenderer is used to render a particular cell, the mappings will be used to retrieve the values from the store and apply them to the properties of the renderer before it renders.

Here's an example of a mapping:

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

This maps store column 0 to the renderer's text GTK property and maps store column 4 to the editable property. For GTK property names you can check the GTK docs. Note that the example above uses a convenience method that adds a column, adds a renderer to it and add an arbitrary number of mapping via params. To add mappings directly to a column, for example a column with multiple renderers, pack the renderers into the column then use TreeViewColumn.AddAttribute or TreeViewColumn.SetAttributes.

You can also set up a custom data function that will be used instead of mappings. This allows you to set the properties of the renderer directly, given a TreeIter and the store - so, if all the data you want to display is trivially derived from your real data objects, you could even have your store only contain a single column of these objects, and use data funcs for all the view columns.

Here's an example of a data func that does exactly what the mapping example above does:

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);
});

Obviously data functions are much more powerful because they enable you not only to use properties of more complex GTK objects, but also to implement more complex display logic - for example, lazily processing derived values only when the cell is actually rendered.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文