6

In a Delphi VCL project, I have created a simple TVirtualStringTree with two columns. The first column will contain text identifying the Name of the data being represented. The data record also contains a status field. The second column is intended to represent the status of the record using an image (16x16 pixel) w/o text.

I have searched demos, but have not mastered the full process for how VTV displays a node, and have not been successful in getting an icon to display in the node of a specified column.

So I have three related questions:

  1. I see how the text is assigned in the OnGetText event, but where should I assign or change the image to reflect the current status in my record?

  2. How do I get the image to actually display in the column?

  3. Am I limited in size for the images, or can they be larger than icons? If so, do I need to change any settings to adjust the height of each row (if possible)?

Ian Boyd
  • 246,734
  • 253
  • 869
  • 1,219
Ashlar
  • 636
  • 1
  • 10
  • 25
  • I may not have been clear in my question. I want the node to display at the node level within a specific column. I edited the question to reflect that. – Ashlar May 09 '17 at 16:00
  • Added Program code – Ashlar May 09 '17 at 23:13
  • I tried adding the if kind ... line and still do not see the icons. I also placed a showmessage at the start of ofGetIMageIndex and found that it is not called during the creation of the nodes, only when I move the mouse into the node once the program is running. – Ashlar May 10 '17 at 13:57

2 Answers2

6

You need to assign (16x16 in your case) TImageList to the TVirtualStringTree.Images property, then handle the event OnGetImageIndex e.g.:

procedure TForm1.VirtualStringTree1GetImageIndex(Sender: TBaseVirtualTree;
  Node: PVirtualNode; Kind: TVTImageKind; Column: TColumnIndex;
  var Ghosted: Boolean; var ImageIndex: Integer);
var
  NodeRec: PNodeRec;
begin
  NodeRec := Sender.GetNodeData(Node);
  if Assigned(NodeRec) then 
  begin
    if (Column = 1) then
    begin 
      if Kind in [ikNormal, ikSelected] then
      begin
        case NodeRec.Status of // check the needed status(es)
          1: ImageIndex := 1; // whichever image you need
          2: ImageIndex := 2; // whichever image you need
          // ...
        end; 
      end;
    end;
  end;
end;

Am I limited in size for the images, or can they be larger than icons? If so, do I need to change any settings to adjust the height of each row (if possible)

Not sure what you meant by that, because you stated you need a 16x16 images. You could use OnGetImageIndexEx if you need different image lists with possibly different dimensions. for variable height you could set toVariableNodeHeight in the TreeOptions.MiscOptionsand handle the OnMeasureItem event. another way to draw graphics into the VTV canvas is to handle the OnBeforeItemPaint/OnAfterItemPaint for example.

kobik
  • 21,001
  • 4
  • 61
  • 121
0

Create an image list 16x16 (Images) and use code like:

procedure TMyTreeView.OnDrawTextEx(Sender: TBaseVirtualTree;
  TargetCanvas: TCanvas; Node: PVirtualNode; Column: TColumnIndex;
  const Text: string; const CellRect: TRect; var DefaultDraw: Boolean);
var i: integer;
begin
    if (Node <> nil) then
    begin
        case Column of
        cStatusColumn:
        begin
            DefaultDraw := false;

            i := 0; // assign the image index from Images list here

            if (i <> -1) then
            begin
                Images.Draw(TargetCanvas, CellRect.Left +
                    ((CellRect.Width - Images.Width) div 2), CellRect.Top, i);
            end;
        end
        else
        begin
            DefaultDraw := true;
        end;
        end;
    end
    else
    begin
        DefaultDraw := true;
    end;
end;
dwrbudr
  • 607
  • 4
  • 8
  • 1
    Using the component editor and selecting the treeview component I can generate a "onDrawText" but not an "onDrawTextEx" event. Selecting the event from the component generates an event for MyForm1, not MyTreeView, I am using a VitrualStringTree component. Is your event owner as shown in the code correct? – Ashlar May 09 '17 at 16:12
  • TMyTreeView is a descendant class of virtual tree view. But you're using the component editor, so in that case just copy/paste the contents of OnDrawTextEx into your OnDrawText event handler. My sample is different from OnGetImageIndex sample above, because it centers the image inside the column. – dwrbudr May 10 '17 at 11:10