Gtk# TreeView,不对非叶节点使用某些列?

Gtk# TreeView, not using certail columns for non-leaf nodes?

下面的代码显示了非叶节点的第二列。但这不是我想要的。我可以只让叶节点有第二列吗?

        var languages = new TreeViewColumn();
        languages.Title = "Programming languages";

        var efficiency = new TreeViewColumn();
        efficiency.Title = "Efficiency";

        var cell = new CellRendererText();
        languages.PackStart(cell, true);
        languages.AddAttribute(cell, "text", 0);

        var cell2 = new CellRendererProgress();
        efficiency.PackStart(cell2, true);
        efficiency.AddAttribute(cell2, "value", 1);

        var treestore = new TreeStore(typeof(string), typeof(int));

        var iter = treestore.AppendValues("scripting languages");
        treestore.AppendValues(iter, "Python", 10);

        iter = treestore.AppendValues("compiling");
        treestore.AppendValues(iter, "C#", 20);

        tree.AppendColumn(languages);
        tree.AppendColumn(efficiency);
        tree.Model = treestore;
        tree.ExpandAll();

经过几十分钟的搜索、试错(因为 Gtk# 缺少任何文档并且在线示例不多),我成功了。我不确定这是否是最有效的方法,但至少它是有效的。如果有人找到更好的方法,请post吧;我会将其标记为答案。

提示是 this old post,使用单元格回调。问题是没有文档说明如何使用该回调。我以为我可以在调试器中找出当前行是否有children,或者当前行的数据,但是没有,我看到的只是IntPtr类型UserData,这是没有用的.经过一番猜测,我发现 tree_model.GetValue(iter, index); 可以检索数据。因为我找不到该行是否有children,所以我添加了一个字段来表示它是否是实际数据。

        efficiency.SetCellDataFunc(cell2, ColumnCallback);

        /*Is language, name, efficiency*/
        var treestore = new TreeStore(typeof(bool), typeof(string), typeof(int));

        var iter = treestore.AppendValues(false, "scripting languages");
        treestore.AppendValues(iter, true, "Python", 10);
        
        iter = treestore.AppendValues(false, "compiling");
        treestore.AppendValues(iter, true, "C#", 50);

    private void ColumnCallback(TreeViewColumn tree_column, CellRenderer cell, ITreeModel tree_model, TreeIter iter)
    {
        var isLanguage = (bool)tree_model.GetValue(iter, 0);
        cell.Visible = isLanguage;
    }

我有一段时间没有使用“C#”,但在研究如何隐藏特定渲染器单元时,我遇到了以下 link。

""

这里搭建的信息如下:

  • 在您的树存储中包含一个可以保存布尔值的隐藏列。
  • 向进度条单元格添加“可见性”属性,该属性引用将放置在每一行的隐藏列单元格中的值。
  • 对于那些应该显示进度条的单元格,将关联的隐藏列单元格设置为值“TRUE”。
  • 对于那些不应显示进度条的单元格,将关联的隐藏列单元格设置为值“FALSE”。

使用这些信息,我构建了一个示例程序,它有一个树视图,其中一列是进度条。我不会在这里列出整个程序,但我会粘贴一些关键位。我意识到这将是 C 代码,但应该能够解释 C# 中的等效代码。

首先,我在树视图中定义了我想要的列(两个可见列和一个隐藏列)。

enum
{
    COLUMN = 0,
    PROG = 1,
    VIS = 2,
    N_COLS          /* Used as a terminator/counter */
}   

然后,我创建了一个视图和模型。以下是为两个可见列设置单元格渲染器的代码片段。

renderer    = gtk_cell_renderer_text_new();
renderer2   = gtk_cell_renderer_progress_new();

gtk_tree_view_column_set_title(col, "Programming Languages");
gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
gtk_tree_view_column_pack_start(col, renderer, TRUE);    /* This will be visible on the tree view */
gtk_tree_view_column_add_attribute(col, renderer, "text", COLUMN);

gtk_tree_view_column_set_title(col2, "Percentage");
gtk_tree_view_append_column(GTK_TREE_VIEW(view), col2);
gtk_tree_view_column_pack_start(col2, renderer2, TRUE);  /* This will be visible on the tree view */
gtk_tree_view_column_add_attribute(col2, renderer2, "value", PROG);
gtk_tree_view_column_add_attribute(col2, renderer2, "visible", VIS);

上面的最后一行代码是我认为您正在寻找的额外位来控制进度条单元格的可见性..

接下来,我定义树视图将有三列(最后一列将被隐藏)。

treestore = gtk_tree_store_new(NUM_COLS, G_TYPE_STRING, G_TYPE_INT, G_TYPE_BOOLEAN);

gtk_tree_store_append(treestore, &toplevel, NULL);
gtk_tree_store_set(treestore, &toplevel, COLUMN, "Scripting Languages", VIS, FALSE, -1);
gtk_tree_store_append(treestore, &child, &toplevel);
gtk_tree_store_set(treestore, &child, COLUMN, "Python", PROG, 62, VIS, TRUE, -1);
/* And so forth for other rows */

其结果会生成一个树视图,其中包含进度条单元格的条件显示。

如前所述,我在 C 中构建了这个示例,但是向进度条单元格添加可见性属性并使其可见性取决于隐藏布尔值 cell/column 中的值的方法应该很容易解释为C#.