如何在 TVirtualStringTree 的列中显示图标或图像?

How to display an icon or image in a column of TVirtualStringTree?

在 Delphi VCL 项目中,我创建了一个包含两列的简单 TVirtualStringTree。第一列将包含标识所表示数据的 Name 的文本。数据记录还包含一个状态字段。第二列旨在使用图像(16x16 像素)w/o 文本来表示记录的状态。

我搜索过demo,但是没有掌握VTV显示节点的完整过程,也没有成功在指定列的节点显示图标

所以我有三个相关的问题:

  1. 我看到了在 OnGetText 事件中文本是如何分配的,但是我应该在哪里分配或更改图像以反映我记录中的当前状态?

  2. 如何让图像实际显示在列中?

  3. 我的图片尺寸有限制吗,或者它们可以比图标大吗?如果是这样,我是否需要更改任何设置来调整每行的高度(如果可能)?

创建一个图像列表 16x16(图像)并使用如下代码:

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;

您需要将(在您的情况下为 16x16)TImageList 分配给 TVirtualStringTree.Images 属性,然后处理事件 OnGetImageIndex 例如:

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)

不确定你的意思,因为你说你需要 16x16 的图像。如果您需要 different 可能具有不同尺寸的图像列表,则可以使用 OnGetImageIndexEx。对于可变高度,您可以在 TreeOptions.MiscOptions 中设置 toVariableNodeHeight 并处理 OnMeasureItem 事件。另一种将图形绘制到 VTV canvas 中的方法是处理 OnBeforeItemPaint/OnAfterItemPaint 例如。