如果 VirtualStringTree 中的节点是多行的(Node.States 中的 vsMultiline),那么我如何才能使该节点中所有列(多行列除外)的文本垂直居中?
我曾尝试使用OnBeforeCellPaint
(using TargetCanvas.TextOut()
) 但这根本不会绘制文本。默认情况下,多行节点的文本始终绘制在节点的顶部。
(对于非多行节点,文本垂直居中绘制)。
如果 VirtualStringTree 中的节点是多行的(Node.States 中的 vsMultiline),那么我如何才能使该节点中所有列(多行列除外)的文本垂直居中?
我曾尝试使用OnBeforeCellPaint
(using TargetCanvas.TextOut()
) 但这根本不会绘制文本。默认情况下,多行节点的文本始终绘制在节点的顶部。
(对于非多行节点,文本垂直居中绘制)。
尝试使用 DrawText(..)
您可以在其上添加文本对齐方式,例如左、右、上、中等。
将 Cellrect 用于 Rect。
在你的情况下,我认为它适用于 OnDrawtext,设置 DefaultText := False;
感谢 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 集,因此无法绘制多线和垂直居中。