0

我正在尝试做一个有几列的 TreeView。第一列是一个ComboBox,这意味着我使用Gtk.CellRendererCombo。问题是,当我从组合框中选择一个值时,我希望单元格中的文本从“”更改为我刚刚选择的值。如果在 Gtk.CellRendererCombo.Edited 事件中我将列 Text 字段设置为 EditedArgs.NewText,这是可行的。

问题是,每次我设置一个值时,我都会创建一个新行,并且我希望文本字段的行为与 Gtk.CellRendererText 中的行为一样,但事实并非如此。该列的每一行的值不是不同的,而是与 Gtk.CellRendererCombo.Text 中设置的值相同

Gtk.CellRenderer 不应该包含任何状态,所以好吧,从我想做的事情来看,使用 Text 字段是一个非常糟糕的主意。

但是,如果我从 Gtk.ListStore 中设置一些值,即我的 TreeView 的模型(这与 Gtk.CellRendererCombo 的模型不同)。设置的值永远不会显示在 ComboBox 的列中。

class Program
{
    private static Gtk.TreeView treeview = null;

    static void OnEdited(object sender, Gtk.EditedArgs args)
    {
        Gtk.TreeSelection selection = treeview.Selection;
        Gtk.TreeIter iter;
        selection.GetSelected(out iter);

        treeview.Model.SetValue(iter, 0, args.NewText); // the CellRendererCombo
        treeview.Model.SetValue(iter, 1, args.NewText); // the CellRendererText

        //(sender as Gtk.CellRendererCombo).Text = args.NewText; // Will set all the Cells of this Column to the Selection's Text
    }

    static void Main(string[] args)
    {
        Gtk.Application.Init();

        Gtk.Window window = new Window("TreeView ComboTest");
        window.WidthRequest = 200;
        window.HeightRequest = 150;

        Gtk.ListStore treeModel = new ListStore(typeof(string), typeof(string));
        treeview = new TreeView(treeModel);

        // Values to be chosen in the ComboBox
        Gtk.ListStore comboModel = new ListStore(typeof(string));
        Gtk.ComboBox comboBox = new ComboBox(comboModel);
        comboBox.AppendText("<Please select>");
        comboBox.AppendText("A");
        comboBox.AppendText("B");
        comboBox.AppendText("C");
        comboBox.Active = 0;

        Gtk.TreeViewColumn comboCol = new TreeViewColumn();
        Gtk.CellRendererCombo comboCell = new CellRendererCombo();
        comboCol.Title = "Combo Column";
        comboCol.PackStart(comboCell, true);
        comboCell.Editable = true;
        comboCell.Edited += OnEdited;
        comboCell.TextColumn = 0;
        comboCell.Text = comboBox.ActiveText;
        comboCell.Model = comboModel;
        comboCell.WidthChars = 20;

        Gtk.TreeViewColumn valueCol = new TreeViewColumn();
        Gtk.CellRendererText valueCell = new CellRendererText();
        valueCol.Title = "Value";
        valueCol.PackStart(valueCell, true);
        valueCol.AddAttribute(valueCell, "text", 1);

        treeview.AppendColumn(comboCol);
        treeview.AppendColumn(valueCol);

        // Append the values used for the tests
        treeModel.AppendValues("comboBox1", string.Empty); // the string value setted for the first column does not appear.
        treeModel.AppendValues("comboBox2", string.Empty);
        treeModel.AppendValues("comboBox3", string.Empty);

        window.Add(treeview);
        window.ShowAll();
        Gtk.Application.Run();
    }
}

我希望 ComboBox 的单元格在其中进行了选择以显示值,但继续可编辑以供以后更改。

如果有人有办法做到这一点,我将非常感谢您的意见。谢谢。

更新:

我的想法是,因为 Gtk.CellRendererCombo 继承自 Gtk.CellRendererText 它只是忽略了单元格中设置的值。现在,我想我可以创建一个继承自 Gtk.CellRendererCombo 的自定义 MyCellRendererCombo 并在为渲染提供时使用单元格中设置的值,但是关于 Gtk.CellRendererText 和 Gtk.CellRendererCombo 之间差异的文档非常薄......我想我应该访问 C 中的实现以了解详细信息。

4

1 回答 1

0

好的,我找到了解决问题的方法,我使用“隐藏”列读取“文本”值。隐藏列包含 Gtk.CellRendererText,Gtk.CellRendererCombo 必须具有与新列的属性映射。

结果代码如下:

class Program
{
    private static Gtk.TreeView treeview = null;

    static void OnEdited(object sender, Gtk.EditedArgs args)
    {
        Gtk.TreeSelection selection = treeview.Selection;
        Gtk.TreeIter iter;
        selection.GetSelected(out iter);

        treeview.Model.SetValue(iter, 1, args.NewText); // the CellRendererText
    }

    static void Main(string[] args)
    {
        Gtk.Application.Init();

        Gtk.Window window = new Window("TreeView ComboTest");
        window.WidthRequest = 200;
        window.HeightRequest = 150;

        Gtk.ListStore treeModel = new ListStore(typeof(string), typeof(string));
        treeview = new TreeView(treeModel);

        // Values to be chosen in the ComboBox
        Gtk.ListStore comboModel = new ListStore(typeof(string));
        Gtk.ComboBox comboBox = new ComboBox(comboModel);
        comboBox.AppendText("<Please select>");
        comboBox.AppendText("A");
        comboBox.AppendText("B");
        comboBox.AppendText("C");
        comboBox.Active = 0;

        Gtk.TreeViewColumn comboCol = new TreeViewColumn();
        Gtk.CellRendererCombo comboCell = new CellRendererCombo();
        comboCol.Title = "Combo Column";
        comboCol.PackStart(comboCell, true);
        comboCol.AddAttribute(comboCell, "text", 1);
        comboCell.Editable = true;
        comboCell.Edited += OnEdited;
        comboCell.TextColumn = 0;
        comboCell.Text = comboBox.ActiveText;
        comboCell.Model = comboModel;
        comboCell.WidthChars = 20;

        Gtk.TreeViewColumn valueCol = new TreeViewColumn();
        Gtk.CellRendererText valueCell = new CellRendererText();
        valueCol.Title = "Value";
        valueCol.PackStart(valueCell, true);
        valueCol.AddAttribute(valueCell, "text", 1);
        valueCol.Visible = false;

        treeview.AppendColumn(comboCol);
        treeview.AppendColumn(valueCol);

        // Append the values used for the tests
        treeModel.AppendValues("comboBox1", "<Please select>"); // the string value setted for the first column does not appear.
        treeModel.AppendValues("comboBox2", "<Please select>");
        treeModel.AppendValues("comboBox3", "<Please select>");

        window.Add(treeview);
        window.ShowAll();
        Gtk.Application.Run();
    }
}
于 2012-12-05T04:34:47.127 回答