I've for a virtualstringtree control on my form which has to display icons from an imagelist for certain nodes. This works fine, however, it also has to display custom drawn icons that are as tall as the node and square, for certain nodes.
I'm using the OnBeforeCellPaint event to draw these images and change the ContentRect to accommodate for the extra space it requires in the item.
ContentRect.Offset(ContentRect.Height + 4, 0);
(The +4 is there to have the same spacing from the "icon" for the text as with the ones loaded from the imagelist)
This method seems to work fine, the nodes are drawn correctly and the selection rectangles are as well. However, the hitboxes for clicking the nodes don't seem to get updated. I have to click the original ContentRect to select the node.
How do I update the hitbox?
What to avoid ?
Don't modify the ContentRect
in the OnBeforeCellPaint
if you want to change the size of a node. The ContentRect
rectangle in the OnBeforeCellPaint
event is for modifying the place, where the cell will be rendered. It doesn't actually modify the size of a node. By that ContentRect
offset you just moved painting out of the node's physical position, out from the position where the node can be clicked.
How to adjust node height ?
The default, fixed node height is defined by the DefaultNodeHeight
property. When you don't know the node height you need in advance, you can write the handler for the OnMeasureItem
event. There you can modify the NodeHeight
parameter value to adjust the height of a node.
When you'll be handling the OnMeasureItem
event, be sure to include the toVariableNodeHeight
option to the TreeOptions.MiscOptions
option set.
How to adjust node width ?
For TVirtualStringTree
control specifically, the node width is calculated by the measured node text width increased by 2 * text margin (adjustable by the TextMargin
property). During the node text width measurement the OnMeasureTextWidth
event is fired having the declared Extent
parameter, which contains the measured text width. By modifying this Extent
parameter, you'll affect the overall width of a node since this event is internally used just for this purpose.
So, to increase each node width e.g. by 20 pixels, you can write the following:
procedure TForm1.VirtualStringTree1MeasureTextWidth(Sender: TBaseVirtualTree;
TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
const Text: string; var Extent: Integer);
begin
Extent := Extent + 20;
end;
Here is the result without and with the text extent modified:
For TVirtualDrawTree
control is the situation much easier. It has the OnGetNodeWidth
event, that is used to specify a node width through its NodeWidth
declared parameter.