【问题标题】:TVirtualStringTree Draw node own image/icon in treeTVirtualStringTree 在树中绘制节点自己的图像/图标
【发布时间】:2014-09-11 00:32:17
【问题描述】:

我需要绘制一些图形作为节点图像。 就像它在 OnGetImageIndex 事件中从 ImageList 中绘制图像一样,但来自 TIcon、TImage、TBitmap 等单一来源。

在我的情况下,所有节点在 UserData 记录中都有自己的图标和位置。

如何将这些图标绘制到节点上?

我在这里找到了这段代码,并尝试适应我的情况:

procedure TForm10.Button1Click(Sender: TObject);
var
  Node: PVirtualNode;
begin
  VirtualStringTree1.AddChild(nil);
  Node := VirtualStringTree1.AddChild(nil);
  VirtualStringTree1.AddChild(Node);
  Node := VirtualStringTree1.AddChild(Node);
  VirtualStringTree1.AddChild(Node);
  VirtualStringTree1.AddChild(Node);
  VirtualStringTree1.AddChild(Node);
end;

procedure TForm10.VirtualStringTree1AfterItemPaint(Sender: TBaseVirtualTree;
  TargetCanvas: TCanvas; Node: PVirtualNode; ItemRect: TRect);
var
  rImage: TRect;
  OffsetLeft: Integer;
  Icon: TIcon;
begin
  rImage := ItemRect;
  Icon := TIcon.Create;
  Icon.LoadFromFile('TestIcon_16.ico');
  with TVirtualStringTree(Sender) do
  begin
    if (toShowRoot in TreeOptions.PaintOptions) then
      OffsetLeft := Indent * (GetNodeLevel(Node) + 1)
    else
      OffsetLeft := Indent * GetNodeLevel(Node);

    Inc(rImage.Left, Margin + OffsetLeft);
    Inc(rImage.Top, (NodeHeight[Node] - Icon.Height) div 2);
    rImage.Right := rImage.Left + Icon.Width;
    rImage.Bottom := rImage.Top + Icon.Height;
  end;
  DrawIcon(TargetCanvas.Handle, rImage.Left, rImage.Top, Icon.Handle);
end;

点击按钮后,我看到:

为什么会这样? 图标大小 100% - 16 x 16 像素。

我在哪里可以解决绘制文本的问题?

我做错了什么?

【问题讨论】:

  • 为什么会这样?因为树不知道您正在这样做,并且不会缩进节点文本来为您的图像腾出空间。
  • 如何通知?还是有其他想法可以做到这一点?
  • 由于我没有使用此组件的任何经验,我只是猜测。但是您不应该改用 OnBeforeItemPaint 事件。我认为通过使用该事件,您可能有机会控制文本的位置,以便它不会绘制在与您的 incons 相同的位置。如果没有别的,您可以通过添加几个空格来更改文本,使其向右移动。在 OnAfterItemPaint 事件中执行此操作将不起作用,因为在事件触发时文本已被绘制。
  • 嗯,首先你需要告诉树腾出一些空间。这就是您可以通过增加OnMeasureTextWidth 事件方法的Extent 参数来实现的。然后在OnDrawText事件方法中自己绘制文本。但更好的是,您将使用图像列表的默认方法。您可以将这些图像存储到图像列表中,并且每个节点存储只是对该图像列表的索引,不是吗?
  • 您肯定会看到一个 32x32 的图标。它发生在 b/c 你加载 16x16 图标并用 DrawIcon 绘制它,它会拉伸它。您可以使用DrawIconEx 或简单地使用TargetCanvas.Draw(x, y, Icon)。无论如何,您泄漏了 TIcon 的内存,我真的不明白为什么您不想使用带有 OnGetImageIndex 的 ImageList,这真​​的是正确的方法吗?...

标签: delphi delphi-xe6 virtualtreeview tvirtualstringtree


【解决方案1】:

不幸的是,VT 依赖于图像列表,不允许使用单独的图像。同时,图像列表只要涉及到项目的插入和删除,就很不方便。因此,作为一种解决方法,您可以为每个图像创建一个图像列表并通过OnGetImageEx 事件处理程序将其返回给 VT。

或者,您可以使用一张空白且透明的图像创建一个虚拟图像列表,以便 VT 知道图像的尺寸并在 AfterPaint 中绘制您自己的自定义图像。

【讨论】:

    猜你喜欢
    • 2017-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-25
    • 2017-10-07
    • 2012-04-24
    • 1970-01-01
    相关资源
    最近更新 更多