问题
In a GTK# application, I am using a TreeView inside a ScrolledWindow, and try to find the position of an item inside the TreeStore to draw lines starting from that item in Cairo. For now, I am using a hard coded value for cell height, which works for few items, but when other font sizes are used or the item list gets longer, there is a visible offset. Is there a method to get the cell height of a TreeView, or another way to get the vertical position of an item in the TreeStore?
Here is the method, that I currently use:
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;
}
You can see the error on the bottom of the screenshot where the lines are not aligned with the items in the TreeView:

回答1:
Reading the documentation, I have come up with the following ugly piece of code:
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;
}
This is what it looks like now:

来源:https://stackoverflow.com/questions/22674065/get-pixel-position-of-item-or-cell-height-in-treeview