VirtualStringTree - 多行节点和垂直居中文本

发布于 2024-11-28 12:56:38 字数 245 浏览 0 评论 0原文

如果 VirtualStringTree 中的节点是多行的(与 Node.States 中的 Multiline 相比),那么如何使该节点中所有列(多行列除外)的文本垂直居中?

我尝试使用 OnBeforeCellPaint (使用 TargetCanvas.TextOut()),但这根本不绘制文本。默认情况下,多行节点的文本始终绘制在节点的顶部。

(对于非多行节点,文本垂直居中绘制)。

If a node in a VirtualStringTree is multiline (vsMultiline in Node.States) then how can i centre the text vertically for all columns (except the multiline column) in that node?

I have tried using the OnBeforeCellPaint (using TargetCanvas.TextOut()) but this does not paint the text at all. By default, the text for a multiline node is always painted at the top of the node.

(For non-multiline nodes the text is painted vertically centred).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

我恋#小黄人 2024-12-05 12:56:38

尝试使用 DrawText(..),

您可以在其上添加文本对齐方式,例如左、右、上、中等。

使用 Cellrect 作为矩形。

在你的情况下,我认为它可以在 OnDrawtext 上使用,设置 DefaultText := False;

Try it using DrawText(..)

you can add text alignment on it such as left, right, top, middle etc.

use the Cellrect for the Rect.

in your case i think it workable on OnDrawtext, set the DefaultText := False;

格子衫的從容 2024-12-05 12:56:38

感谢 XBasic3000,我能够想出这个解决方案,它涵盖了几乎所有可能的组合:

procedure TForm1.TreeDrawText(
  Sender: TBaseVirtualTree; TargetCanvas: TCanvas; Node: PVirtualNode;
  Column: TColumnIndex; const Text: WideString; const CellRect: TRect;
  var DefaultDraw: Boolean);
var DrawFormat : Cardinal;
R : TRect;
s : WideString;
NodeWidth,EllipsisWidth : Integer;
Size: TSize;
begin
     if not (Column in [yourmultilinecolumns]) then
     begin
          DefaultDraw := False;
          R := CellRect;
          GetTextExtentPoint32W(TargetCanvas.Handle, PWideChar(Text), Length(Text), Size);
          NodeWidth := Size.cx + 2 * Tree.TextMargin;
          GetTextExtentPoint32W(TargetCanvas.Handle, '...', 3, Size);
          EllipsisWidth := Size.cx;
          if ((NodeWidth - 2 * Tree.TextMargin) > R.Right - R.Left) then
               s := EllipseString(TargetCanvas.Handle, Text, R.Right - R.Left, EllipsisWidth)
          else s := Text;
          DrawFormat := DT_NOPREFIX or DT_VCENTER or DT_SINGLELINE;
          Windows.DrawTextW(TargetCanvas.Handle, PWideChar(s), Length(s), R, DrawFormat);
     end;
end;

EllipseString() 方法与 VirtualTrees.pas 中的 VirtualTrees.ShortenString() 非常相似。

唯一的问题是无法在其他列上绘制多行文本。您必须指定多行列集,因此无法绘制多行和垂直居中。

Thanks to XBasic3000, i was able to come up with this solution, which covers almost every possible combination:

procedure TForm1.TreeDrawText(
  Sender: TBaseVirtualTree; TargetCanvas: TCanvas; Node: PVirtualNode;
  Column: TColumnIndex; const Text: WideString; const CellRect: TRect;
  var DefaultDraw: Boolean);
var DrawFormat : Cardinal;
R : TRect;
s : WideString;
NodeWidth,EllipsisWidth : Integer;
Size: TSize;
begin
     if not (Column in [yourmultilinecolumns]) then
     begin
          DefaultDraw := False;
          R := CellRect;
          GetTextExtentPoint32W(TargetCanvas.Handle, PWideChar(Text), Length(Text), Size);
          NodeWidth := Size.cx + 2 * Tree.TextMargin;
          GetTextExtentPoint32W(TargetCanvas.Handle, '...', 3, Size);
          EllipsisWidth := Size.cx;
          if ((NodeWidth - 2 * Tree.TextMargin) > R.Right - R.Left) then
               s := EllipseString(TargetCanvas.Handle, Text, R.Right - R.Left, EllipsisWidth)
          else s := Text;
          DrawFormat := DT_NOPREFIX or DT_VCENTER or DT_SINGLELINE;
          Windows.DrawTextW(TargetCanvas.Handle, PWideChar(s), Length(s), R, DrawFormat);
     end;
end;

The EllipseString() method is very similar to VirtualTrees.ShortenString() in VirtualTrees.pas.

The only isue is the inability to draw multiline text on other columns. You must specify the multilinecolumns set, so there is no capability to draw multiline and vertically centred.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文