Frage

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?

War es hilfreich?

Lösung

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:

enter image description here

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.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top