【问题标题】:How to display an icon or image in a column of TVirtualStringTree?如何在 TVirtualStringTree 的列中显示图标或图像?
【发布时间】:2017-10-07 02:42:40
【问题描述】:

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

我搜索了demo,但没有掌握VTV如何显示节点的完整流程,也没有成功获得图标显示在指定列的节点中。

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

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

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

  3. 图像的大小是否受到限制,或者它们是否可以大于图标?如果是这样,我是否需要更改任何设置来调整每行的高度(如果可能)?

【问题讨论】:

  • 我的问题可能不清楚。我希望节点显示在特定列中的节点级别。我编辑了问题以反映这一点。
  • 添加程序代码
  • 我尝试添加 if kind ... 行,但仍然看不到图标。我还在ofGetIMageIndex的开头放了一个showmessage,发现在创建节点的时候没有调用,只有在程序运行的时候鼠标移到节点上才调用。

标签: delphi virtualtreeview tvirtualstringtree


【解决方案1】:

创建一个 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;

【讨论】:

  • 使用组件编辑器并选择树视图组件,我可以生成“onDrawText”但不能生成“onDrawTextEx”事件。从组件中选择事件会为 MyForm1 而不是 MyTreeView 生成事件,我使用的是 VitrualStringTree 组件。代码中显示的活动所有者是否正确?
  • TMyTreeView 是虚拟树视图的后代类。但是您使用的是组件编辑器,因此在这种情况下,只需将 OnDrawTextEx 的内容复制/粘贴到您的 OnDrawText 事件处理程序中即可。我的示例与上面的 OnGetImageIndex 示例不同,因为它将图像居中在列内。
【解决方案2】:

您需要将(在您的情况下为 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;

图片的大小是否受到限制,或者它们是否可以大于图标? 如果是这样,我是否需要更改任何设置来调整每个设置的高度 行(如果可能)

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

【讨论】:

  • 我同意并这样做了。
猜你喜欢
  • 1970-01-01
  • 2023-01-10
  • 1970-01-01
  • 2014-09-11
  • 1970-01-01
  • 2019-11-08
  • 2016-10-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多