2

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

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

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

4

2 回答 2

3

尝试使用 DrawText(..)

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

将 Cellrect 用于 Rect。

在你的情况下,我认为它适用于 OnDrawtext,设置 DefaultText := False;

于 2011-08-10T06:04:27.620 回答
2

感谢 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() 非常相似。

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

于 2011-08-10T07:15:05.620 回答