Получить пиксельную позицию элемента или высоту ячейки в дереве

В приложении GTK# я использую TreeView внутри ScrolledWindow и пытаюсь найти положение элемента внутри TreeStore, чтобы рисовать линии, начинающиеся с этого элемента в Каире. На данный момент я использую жестко закодированное значение высоты ячейки, которое работает для нескольких элементов, но когда используются другие размеры шрифта или список элементов становится длиннее, появляется видимое смещение. Есть ли способ получить высоту ячейки TreeView или другой способ получить вертикальное положение элемента в TreeStore?

Вот метод, который я сейчас использую:

int GetYPositionForPort (TreeView tree, TreeStore store, Port selectedPort)
{
    // Is there a way to get the cell height?
    int cellHeight = 24;
    // We start in the middle of the first Treeview item
    int position = cellHeight / 2;

    ScrolledWindow treeParent = tree.Parent as ScrolledWindow;
    if (treeParent != null) {
        position -= Convert.ToInt32 (treeParent.Vadjustment.Value);
    }
    TreeIter clientIter;
    TreeIter portIter;
    if (store.GetIterFirst (out clientIter)) {
        do {
            if (store.IterHasChild (clientIter) 
                && tree.GetRowExpanded (store.GetPath (clientIter))) {
                if (store.IterChildren (out portIter, clientIter)) {
                    do {
                        position += cellHeight;
                    } while (((Port)store.GetValue(portIter, 0) != selectedPort 
                        || (Client)store.GetValue(clientIter, 0) != selectedPort.Client) 
                        && store.IterNext(ref portIter));
                }
            }
            //Necessary because the first Treeview item only counts as 1/2 cell height.
            if (((Client)store.GetValue (clientIter, 0)) == selectedPort.Client) {
                break;
            }
            position += cellHeight;
        } while (store.IterNext(ref clientIter));
    }
    return position;
}

Вы можете увидеть ошибку в нижней части скриншота, где строки не выровнены с элементами в TreeView:

Скриншот приложения


person Residuum    schedule 26.03.2014    source источник


Ответы (1)


Читая документацию, я придумал следующий уродливый кусок кода:

int GetCellHeight (TreeView tree)
{
    if (_cellHeight > 0) {
        return _cellHeight;
    }
    int offsetX;
    int offsetY;
    int cellWidth;
    Gdk.Rectangle rectangle = new Gdk.Rectangle ();
    TreeViewColumn column = tree.GetColumn (0);

    // Getting dimensions from TreeViewColumn
    column.CellGetSize(rectangle, out offsetX, out offsetY, 
        out cellWidth, out _cellHeight);

    // And now get padding from CellRenderer
    CellRenderer renderer = column.CellRenderers[0];
    _cellHeight += (int)renderer.Ypad;
    return _cellHeight;
}

Вот как это выглядит сейчас: Текущее состояние программы

person Residuum    schedule 02.04.2014