Delphi 如何将TTreeview保存到Windows并保持其层次结构?
我希望能够将我的Treeview保存到Windows并保持其层次结构,但似乎无法理解递归的魔力 假设我有两种不同的对象类型:Delphi 如何将TTreeview保存到Windows并保持其层次结构?,delphi,Delphi,我希望能够将我的Treeview保存到Windows并保持其层次结构,但似乎无法理解递归的魔力 假设我有两种不同的对象类型: TMyFolderNode (represents a folder in the tree) TMyItemNode (represents a node containing a stringlist of text for example) 树视图将在运行时填充,对于添加的每个节点,都包含指向这些对象之一的指针-通常,TMyFolderNode将表示TMyItem
TMyFolderNode (represents a folder in the tree)
TMyItemNode (represents a node containing a stringlist of text for example)
树视图将在运行时填充,对于添加的每个节点,都包含指向这些对象之一的指针-通常,TMyFolderNode将表示TMyItemNode的子节点的父节点
所以基本上,如果我的树视图是这样的:
..\Vehicles
..\Vehicles\Bikes
..\Vehicles\Cars
..\Vehicles\Cars\Classic
..\Vehicles\Cars\Classic\1996 Shelby Cobra.txt
..\Vehicles\Cars\Classic\Corvette Stingray.txt
..\Vehicles\Cars\Classic\Jaguar E-Type.txt
..\Vehicles\Cars\Tuner
..\Vehicles\Cars\Tuner\Toyota Supra RZ.txt
..\Vehicles\Trucks
保存treeview时,Windows中的结构应如下所示:
..\Vehicles
..\Vehicles\Bikes
..\Vehicles\Cars
..\Vehicles\Cars\Classic
..\Vehicles\Cars\Classic\1996 Shelby Cobra.txt
..\Vehicles\Cars\Classic\Corvette Stingray.txt
..\Vehicles\Cars\Classic\Jaguar E-Type.txt
..\Vehicles\Cars\Tuner
..\Vehicles\Cars\Tuner\Toyota Supra RZ.txt
..\Vehicles\Trucks
这就是我所尝试的:
procedure SaveTreeViewStructure(TreeView: TTreeView; const OutDirectory: string);
var
RootDir, SubDir: string;
Node: TTreeNode;
// the recursive procedure
procedure SaveNode(Node: TTreeNode);
var
Obj: TObject;
Child: TTreeNode;
begin
Obj := TObject(Node.Data);
// node type is a folder/parent, so create the folder in windows...
if Obj.ClassType = TMyFolderNode then
begin
ForceDirectories(RootDir + '\' + Node.Text);
end;
// node is a type holding data we can save to text file...
if Obj.Create.ClassType = TMyItemNode then
begin
with TMyItemNode(Obj) do
begin
// save the file as .txt...
end;
end;
Child := Node.GetFirstChild;
while Assigned(Child) do
begin
SaveNode(Child);
Child := Child.GetNextSibling;
end;
end;
begin
RootDir := OutDirectory + '\';
SubDir := '';
Node := nil;
if ForceDirectories(RootDir) then // make sure base folder exists first
begin
Node := TreeView.Items[0]; // start from the first tree node (TopItem causes problems)
while Assigned(Node) do // until node is no longer assigned
begin
SaveNode(Node); // call the recursive procedure
Node := Node.GetNextSibling; // go to the next node
end;
end;
end;
如果我尝试只保存TMyFolderNode节点,它们不会在适当的子文件夹等中创建,然后当我尝试保存文本TMyItemNode时,我无法找到文件错误,可能是因为文件夹保存不正确
显然,我不完全理解递归背后的逻辑,我知道这意味着在满足条件之前调用它自己,例如我们到达树中的最后一个节点,但我似乎无法理解这一点
那么,如何将我的Treeview保存到Windows中的一个基本文件夹中,递归过程将在其中创建所需的子目录,并将常规节点项保存在正确的位置
我的方法错了吗?我第一次尝试了for循环,但是文件夹一直在翻倍和其他奇怪的事情
非常感谢。正如500-内部服务器错误所指出的,答案是更改我传递给递归过程的路径 我还必须以字符串格式获取节点的路径,然后将其用作新路径:
function NodeToStringPath(Node: TTreeNode; var Path: string): string;
begin
Result := '';
Path := Node.Text + '\' + Path;
if Node.Level = 0 then
begin
Result := Path
end
else
Result := NodeToStringPath(Node.Parent, Path);
end;
function RemoveLastFolder(var S: string): string;
begin
Result := '';
repeat
Delete(S, Length(S), 1)
until
(S[Length(S)] = '\') or (S = '');
Result := S;
end;
procedure SaveTreeViewStructure(TreeView: TTreeView; const OutDirectory: string);
var
RootDir, SubDir: string;
Node: TTreeNode;
// the recursive procedure
procedure SaveNode(Node: TTreeNode);
var
sPath: string;
Obj: TObject;
Child: TTreeNode;
begin
Obj := TObject(Node.Data);
// node type is a folder/parent, so create the folder in windows...
if Obj.ClassType = TMyFolderNode then
begin
SubDir := NodeToStringPath(Child, sPath);
ForceDirectories(RootDir + SubDir);
end;
// node is a type holding data we can save to text file...
if Obj.Create.ClassType = TMyItemNode then
begin
with TMyItemNode(Obj) do
begin
// save the file as .txt...
SubDir := NodeToStringPath(Node, sPath);
SubDir := RemoveLastFolder(SubDir);
//...
end;
end;
Child := Node.GetFirstChild;
while Assigned(Child) do
begin
SaveNode(Child);
Child := Child.GetNextSibling;
end;
end;
begin
RootDir := OutDirectory + '\';
SubDir := '';
Node := nil;
if ForceDirectories(RootDir) then // make sure base folder exists first
begin
Node := TreeView.Items[0]; // start from the first tree node (TopItem causes problems)
while Assigned(Node) do // until node is no longer assigned
begin
SaveNode(Node); // call the recursive procedure
Node := Node.GetNextSibling; // go to the next node
end;
end;
end;
经过测试,似乎可以工作,但它不是100%,但在尝试保存文本文件节点类型时,我需要从字符串中删除文件夹名称的最后一部分,这也很麻烦
我确信有一种更干净的方法可以实现这一点,但这是我能做到的最好的方法,我只需要调整一些东西,但要将树状视图的结构保存到windows,感觉需要做很多工作。而不是在递归过程中直接使用RootDir,将相对路径作为参数传入,并根据需要附加到该路径。@500 InternalServerError谢谢提示,我想我已经可以使用了,但现在没有时间进行测试。我所做的是获取字符串的节点路径,然后将其作为文件路径传递。我将在稍后发布我更改的内容,希望在稍后测试时它能正常工作。@500 InternalServerError我发布了我的答案,但如果您愿意,您也可以发布您的解决方案: