Frage

What I'm trying to do it a TreeView that have several columns. The first column is a ComboBox, which means that I use Gtk.CellRendererCombo. The thing is, when I selected a value from the ComboBox, I'd like the Text from the cell to change from "" to the value I just selected. It feasible if at the Gtk.CellRendererCombo.Edited event I set the columns Text field to the EditedArgs.NewText.

The problem is, each time I set a value, I create a new row, and I'd like the Text Field to act like it does in the Gtk.CellRendererText, but it doesn't. It's not a different value for each row at that column, but the same value as setted in the Gtk.CellRendererCombo.Text

The Gtk.CellRenderer should not contain any state, so OK, using the Text field is a really bad idea from what I'm trying to do.

But if I set some value from the Gtk.ListStore that is the Model of my TreeView (Which is different from the Model for the Gtk.CellRendererCombo). The values setted will never show at the Column of the 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();
    }
}

I'd like the Cell of the ComboBox in which the selection has been made to show the value, but continue to be editable for later changes.

If someone has a way of doing this, I would be very grateful for you input. thanks.

Update:

What I think, because Gtk.CellRendererCombo inherits from Gtk.CellRendererText it just ignores the value setted in the cell. Now, I guess I could create a custom MyCellRendererCombo that inherits from Gtk.CellRendererCombo and use the value setted in the cell when supplied for the rendering, but the documentation on the difference between Gtk.CellRendererText and Gtk.CellRendererCombo is quite slim... I guess I should visit the implementation in C to know the details.

War es hilfreich?

Lösung

Ok, I've found a solution to my problem, I use a "hidden" column in which I read the "text" value. The hidden column contains the Gtk.CellRendererText, the Gtk.CellRendererCombo must have an Attribute Mapping with the new Column.

The resulting code is below:

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();
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top