Delphi填充VirtualStringTree的理想方法是什么?

时间:2013-04-02 16:51:41

标签: delphi record nodes virtualtreeview tvirtualstringtree

所以我正在使用Delphi 2010,自从我开始使用VirtualTreeView(正是VirtualStringTree)以来已经有一段时间了......似乎我正在以错误的方式做某事......因为事情不起作用我期待着。

我正在尝试使用指向存储在数据记录中的文件/子文件夹描述的节点填充我的VST,并通过扫描用户给出的路径生成..(更多详细信息如下图所示)

enter image description here

因为它显示节点以奇怪的方式显示..&无论我做什么节点数据都没有正确初始化..列“文件”的节点标题是唯一运作良好的。

&安培;这是我使用的代码:

1- 节点数据声明

type  nodeData=record
            Text, Size, Path:String;
            ImageIndex:Integer;
           end;

  PNodeData=^nodeData;


var hashmap:TDictionary<String, PVirtualNode>; // hashmap-> to store parent nodes (Folder)
    filesList:TDictionary<Integer,nodeData>; // fileList to store records of data

2- 方法

a)扫描用户给出的路径

procedure AddAllFilesInDir(const Dir:String);
begin
// it scans the path 'Dir' and extract the "name & size" of each file/folder found in this dir
end;

b)生成 filesList tdictionary ...    &安培;图像存储在“ treeImageLIst ”中,该链接到 treeview.images 属性

procedure addFileToList(Name, Size:String);
var d:nodeData;
    parent:String;
    SHFileInfo :TSHFileINfo;
    Icon:TIcon;
begin
parent:=ExtractFileDir(Name);

//Get The Icon That Represents The File/Folder
SHGetFileInfo(PChar(Name), 0, SHFileInfo,  SizeOf(SHFileInfo),
                SHGFI_ICON or SHGFI_SMALLICON );


Icon := TIcon.Create;
Icon.Handle := SHFileInfo.hIcon;

// set The Name, Size, Path
d.Name:=ExtractFileName(Name);
d.Size:=Size;
d.Path:=parent;

// set the ImageIndex
d.ImageIndex:=Form1.treeImageList.AddIcon(Icon);

// add the node to fileList
filesList.Add(filesList.Count, d);

// Destroy the Icon
DestroyIcon(SHFileInfo.hIcon);
Icon.Free;
end;

c)创建树“theTree”

procedure createTree();
var theNode, Node:PVirtualNode;
    d:PNodeData;
    parent:String;
    nData:nodeData;
    i:integer;
begin

for i := 0 to filesList.Count - 1 do
begin

 nData:=filesList.Items[i];  parent:=nData.Path;

 if(hashmap.ContainsKey(parent))then theNode:=hashmap.Items[parent]
 else theNode:=nil;

 Node:=Form1.theTree.AddChild(theNode);

 // add a checkbox and make it checked
 Node.CheckType:=ctCheckBox;
 Node.CheckState:=csCheckedNormal;

 // get the newly created node data
 d:=Form1.theTree.GetNodeData(Node);

 // assign a data  to the newly created node
 d^:=nData;

 // add the node to hashmap if it's a new folder node
 if((ExtractFileExt(nData.Text)='')and(not hashmap.ContainsKey(nData.Path+'\'+nData.Text)))
 then hashmap.Add(nData.Path+'\'+nData.Text, Node);

end;

 Form1.theTree.Expanded[Form1.theTree.TopNode]:=True;
end;

d)树视图事件

procedure TForm1.theTreeFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
var d:PNodeData;
begin
  d := Sender.GetNodeData(Node);
  Finalize(d^);
end;


procedure TForm1.theTreeGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
  Column: TColumnIndex; TextType: TVSTTextType; var CellText: String);
var d:PNodeData;
begin
 d:=Sender.GetNodeData(Node);

 case Column of
  0:CellText:=d^.Text;
  1:CellText:=d^.Size;
 end;
end;


procedure TForm1.theTreeGetImageIndex(Sender: TBaseVirtualTree;
  Node: PVirtualNode; Kind: TVTImageKind; Column: TColumnIndex;
  var Ghosted: Boolean; var ImageIndex: Integer);

var d:PNodeData;
begin
d:=Sender.GetNodeData(Node);

if(Kind in [ikNormal, ikSelected])then
begin
 if(Column=0)then ImageIndex:=d^.ImageIndex;
end;

end;

我现在真的很沮丧......而且我不知道为什么节点没有正确创建。尽管我测试了记录数据&amp;它们创建得很好但是当我测试 onNodeClick 事件时,我发现Node指向的数据记录只返回第一个字段..而其他字段为空或者它们生成 Access违规例外

1 个答案:

答案 0 :(得分:0)

您发布的代码太多,无法提出有用的问题。每天都会发布数百个问题,这些问题没有代码示例,也没有足够的代码示例。你走了另一条路,远远超过了另一条路。

“填充”虚拟树视图的最佳方法是不填充它。相反,您只需设置rootNodeCount然后迭代,必要时设置子节点的子节点计数。对于折叠节点,树视图知道有子节点或者没有子节点就足够了。展开子节点后,您可以填充子元素。

请注意,当您按照虚拟控件的方式执行操作时,您不会编写大量代码。相反,您只是“回答有关模型对象的基本状态的问题”。有多少个根节点?你告诉虚拟树这个号码。然后,从那里,你只需回答问题。根节点下的节点#3的列0的文本是什么? (它调用您处理的事件,并返回该信息)。请注意,初始化DATA是大多数VirtualTreeViews新手常常误解的内容。理想情况下,DATA应包含指向真实模型对象的指针,该对象可以回答VirtualTreeView提出的问题。回答这些问题的最有效的类可能甚至不需要为树中的每个可见节点实例化一个真实的模型对象,尽管这当然是可接受的和常见的。重要的是你要明白它并不是严格的本质。

其次,如果您的目标是使用TVirtualTreeView来模拟shell资源管理器,那么该代码已经为您完成,请查看高级 VT演示的子部分可从VirtualTreeview获取网站。请参阅我在此处指出的标签:

enter image description here