Question

I have a ListStore that is filtered and then sorted. It looks something like this:

// Create a model for the cards
cardListStore = new ListStore (typeof (Card));

// Set up the tree view
cardFilter = new TreeModelFilter (cardListStore, null);
cardFilter.VisibleFunc = new TreeModelFilterVisibleFunc (FilterCards);
cardSort = new TreeModelSort (cardFilter);
cardTreeView.Model = cardSort;

I want to have a get a context menu specific for each row when I right-click on it. My click handler looks something like this:

[GLib.ConnectBeforeAttribute]
void HandleCardTreeViewButtonPressEvent (object o, ButtonPressEventArgs args)
{
    if (args.Event.Button != 3)
        return;

    TreePath path;
    // If right click on empty space
    if (!cardTreeView.GetPathAtPos (Convert.ToInt32 (args.Event.X),
                                    Convert.ToInt32 (args.Event.Y),
                                    out path)) {
        MakeCardEmptySpaceContextMenu ().Popup ();
        return;
    }

    TreeIter iter;
    if (!cardListStore.GetIter (out iter, path))
        return;

    Card card = (Card) cardListStore.GetValue (iter, 0);

    MakeCardContextMenu (card, iter).Popup ();
}

This works when the ListStore is not filtered or sorted. But when it is, it gives the wrong row.

For example, say the rows look like this before they are sorted:

A
B
C

And after they are sorted, they look like this:

B
A
C

Right-clicking on the second row ("A") will give you "B", because that's where B was before the model was sorted. The same thing happens for filtering. Say the model, after it is filtered, looks like this:

A
C

Right-clicking on the second row ("C") would still give you "B".

Any idea how to work around this?

Was it helpful?

Solution

I just needed to get the iter and the value from cardSort, instead of cardListStore.

if (!cardListStore.GetIter (out iter, path))
    return;

Card card = (Card) cardListStore.GetValue (iter, 0);

becomes

if (!cardSort.GetIter (out iter, path))
    return;

Card card = (Card) cardSort.GetValue (iter, 0);

OTHER TIPS

Looks like there is a filter between you and the data, and that is what is displayed by the tree. You are looking at the data behind the tree...

Now, I'm not familiar with GTK, but perhaps something like

TreeModelSort.convert_path_to_child_path ?

There must bet a way to get what row of the VIEW of the MODEL you are looking at, and then translate that back to real model data.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top