我正在使用VT.Background在VT中显示带有几列的背景图像.
但我无法找到一种方法为细胞使用不同的颜色,因为它们隐藏了背景图像.
我曾尝试使用,OnBeforeItemErase但如果我使用EraseAction := eaColor单元格上的背景位图区域也正在绘制,如果我使用eaDefault的颜色没有被应用.
知道如何做到这一点?
我需要一个可以与Virtual Treeview一起使用的树实现,它不会消耗太多内存,易于使用,并且与VT一样快(也就是说,当我将数据存储在VT本身时)
我尝试过Linas的svTree - 它易于使用,但不如我希望的那么快和内存友好.
此外,只想指出我的应用程序将管理数千个节点.:)
你推荐什么免费图书馆?您是否能够构建一个如何在Virtual Treeview中使用它的最小演示?
我正在从标准的TTreeView转换树视图以使用TVirtualStringTree.我最后的挑战是实现一个功能,我需要在已知节点图标的顶部绘制"通过/失败"状态指示器.使用TTreeView我使用:
var
R : TRect;
begin
R := Node.DisplayRect( True );
StatusIconList.Draw( TreeView1.Canvas,
R.Left - StatusIconList.Width - 14,
R.Top,
3 {MyOverlayImageIndex} );
Run Code Online (Sandbox Code Playgroud)
结果是基本图标上的红叉,如下所示:

有了TVirtualStringTree,我希望找到更好的方法,或者为所需的叠加图标位置获得更好的已知位置.我正在做:
procedure DrawFailed;
var
R : TRect;
begin
R := CellRect;
StatusIconList.Draw( TargetCanvas,
R.Left - StatusIconList.Width + 49 + Sender.GetNodeLevel( Node ) * 16,
R.Top,
siiFailed );
end;
Run Code Online (Sandbox Code Playgroud)
这是最好的解决方案吗?在没有可怕的节点级别调用的情况下,是否有更好的方法来获取基本图标的左上角?
如果我没弄错的话,TVirtualStringTree树视图中不可能有不可见的节点,因为没有启用,可见或其他属性.我这是对的吗?
如果是,我怎么设法有一个不可见的节点?
我树的结构:
当我在整个树上执行FirstNode/GetNextNode循环时,我可以找到子节点16,让我打印出第一列的文本.我也可以检查节点,看看他有一个以前的兄弟,但没有下一个兄弟,例如节点高度为18.
那我是怎么做到的?
我想选择所有根节点或所有子节点(不是VirtualTreeView中的所有节点).
我试图使用此代码来选择所有根节点:
procedure SelectAllRoots;
var
Node: PVirtualNode;
begin
Form1.VirtualStringTree1.BeginUpdate;
Node := Form1.VirtualStringTree1.GetFirst;
while True do
begin
if Node = nil then
Break;
if not (vsSelected in Node.States) then
Node.States := Node.States + [vsSelected];
Node := Form1.VirtualStringTree1.GetNext(Node);
end;
Form1.VirtualStringTree1.EndUpdate;
end;
Run Code Online (Sandbox Code Playgroud)
我可以说有一个小故障.选择不完整或卡住.我究竟做错了什么 ?
编辑:
我使用MultiSelection.
检查节点是否可见很容易.但我不知道如何正确定义该节点在屏幕上显示.我只能这样发现:
BottomNode := Tree.BottomNode;
Node := Tree.TopNode;
IdBottomNode := Tree.AbsoluteIndex(BottomNode);
while Tree.AbsoluteIndex(Node) <> IdBottomNode do
begin
Node := Node.NextSibling;
if not Assigned(Node) then
Break;
end;
Run Code Online (Sandbox Code Playgroud)
(代码没有检查)
但我认为这是相当粗糙的方式.可能是有更准确的方法吗?
我正在尝试使用TButton创建节点。我创建节点和链接到节点的按钮。在事件TVirtualStringTree.AfterCellPaint上,我初始化按钮上的BoundsRect。但是该按钮始终显示在第一个节点中。
你对这个问题有想法吗?
type
TNodeData = record
TextValue: string;
Button: TButton;
end;
PNodeData = ^TNodeData;
procedure TForm1.FormCreate(Sender: TObject);
procedure AddButton(__Node: PVirtualNode);
var
NodeData: PNodeData;
begin
NodeData := VirtualStringTree1.GetNodeData(__Node);
NodeData.Button := TButton.Create(nil);
with NodeData.Button do
begin
Parent := VirtualStringTree1;
Height := VirtualStringTree1.DefaultNodeHeight;
Caption := '+';
Visible := false;
end;
end;
procedure InitializeNodeData(__Node: PVirtualNode; __Text: string);
var
NodeData: PNodeData;
begin
NodeData := VirtualStringTree1.GetNodeData(__Node);
NodeData.TextValue := __Text;
end;
var
Node: PVirtualNode;
begin
VirtualStringTree1.NodeDataSize := SizeOf(TNodeData);
Node := VirtualStringTree1.AddChild(nil);
InitializeNodeData(Node, 'a');
Node := VirtualStringTree1.AddChild(Node);
InitializeNodeData(Node, …Run Code Online (Sandbox Code Playgroud) 我有一个TVirtualStringTree以两种不同方式格式化节点文本的实例。实现基于使用toShowStaticText在StringOptions这个问题的答案接受描述:VirtualTreeView -不同颜色的文字在同一节点
在我MultiLine为节点设置标志之前,一切都很好。现在OnPaintText事件将不再被触发TextType = ttStatic。
这种行为的原因可以在TCustomVirtualStringTree.DoPaintNode方法中找到,显然是为了:
// ... and afterwards the static text if not centered and the node is not multiline enabled.
if (Alignment <> taCenter) and not (vsMultiline in PaintInfo.Node.States) and (toShowStaticText in TreeOptions.FStringOptions) then
begin
S := '';
with PaintInfo do
DoGetText(Node, Column, ttStatic, S);
if Length(S) > 0 then
PaintStaticText(PaintInfo, TextOutFlags, S);
end;
Run Code Online (Sandbox Code Playgroud)
不过,我希望在同一个MultiLineNode.js文件中有两种不同的文本格式。我怎样才能做到这一点?
在Delphi VCL项目中,我创建了一个简单TVirtualStringTree的两列.第一列将包含标识Name所表示数据的文本.数据记录还包含状态字段.第二列用于表示使用没有文本的图像(16x16像素)的记录状态.
我已经搜索了演示,但还没有掌握VTV如何显示节点的完整过程,并且还没有成功获得在指定列的节点中显示的图标.
所以我有三个相关的问题:
我看到在OnGetText事件中如何分配文本,但是我应该在哪里分配或更改图像以反映记录中的当前状态?
如何让图像实际显示在列中?
我的图像尺寸有限,还是比图标大?如果是这样,我是否需要更改任何设置以调整每行的高度(如果可能)?
假设我在虚拟模式下使用VirtualStringTree。
我想指出树有一些节点:
VirtualStringTree1.RootNodeCount := 999983;
Run Code Online (Sandbox Code Playgroud)
由于该树处于虚拟模式:
我的底层TList中发生了一些事情(例如在索引处797,977),这将导致节点之一(如果它可见)需要更改其Selected状态。
由于虚拟树中的所有内容都基于Node.Index,因此理想情况下应该有一种方法来指示选择了索引:
VirtualStringTree1.RootNodeCount := 999983;
VirtualStringTree1.Selected[797977] := True; //indicate that node at index 797977 is now selected
Run Code Online (Sandbox Code Playgroud)
但是树没有重载来按索引设置选择。
改变节点选定状态的唯一方法是:
PVirtualNodeVirtualStringTree1.Selected[node] := True;当我没有节点时,如何将节点标记为选中?
虚拟模式下的Windows ListView控件可以非常简单地解决这个问题。
Node.Index所以你会得到一个LVN_GETDISPINFO回调。那就是当您填充回调结构,并根据需要向树提供它所要求的信息时:
但为了简单起见,您可以将其视为:
procedure TForm1.VirtualStringTree1GetSelected(Sender: TBaseVirtualTree; Node: PVirtualNode; var Result: Boolean);
begin …Run Code Online (Sandbox Code Playgroud)