procedure TCustomShellTreeView.UpdateTree;
procedure RecordNodeState(const ANode: TTreeNode; const AExpandedPaths: TStringList);
var
currentNode: TTreeNode;
firstChild: TTreeNode;
begin
currentNode := ANode;
while currentNode <> nil do
begin
if currentNode.Expanded then
begin
AExpandedPaths.Add(GetPathFromNode(currentNode));
firstChild := currentNode.GetFirstChild();
if firstChild <> nil then
RecordNodeState(firstChild, AExpandedPaths);
end;
currentNode := currentNode.GetNextSibling();
end;
end;
procedure RestoreNodeState(const ANode: TTreeNode; const ARefresh: boolean;
const AExpandedPaths: TStringList);
var
currentNode: TTreeNode;
firstChild: TTreeNode;
begin
currentNode := ANode;
while currentNode <> nil do
begin
if AExpandedPaths.IndexOf(GetPathFromNode(currentNode)) >= 0 then
begin
currentNode.Expanded := True;
if ARefresh then
Refresh(currentNode);
firstChild := currentNode.GetFirstChild();
if firstChild <> nil then
RestoreNodeState(firstChild, ARefresh, AExpandedPaths);
end
else
currentNode.Expanded := False;
currentNode := currentNode.GetNextSibling();
end;
end;
var
node: TTreeNode;
topNodePath: String;
selectedPath: String;
expandedPaths: TStringList;
selectedFile: String;
fileList: TCustomShellListView;
begin
expandedPaths := TStringList.Create;
Items.BeginUpdate;
try
topNodePath := ChompPathDelim(GetPathFromNode(TopItem));
selectedPath := GetPathFromNode(Selected);
if Assigned(FShellListView) and Assigned(FShellListView.Selected) then
selectedFile := FShellListView.Selected.Caption
else
selectedFile := '';
node := Items.GetFirstNode;
RecordNodeState(node, expandedPaths);
RestoreNodeState(node, true, expandedPaths);
try
Path := selectedPath;
TopItem := Items.FindNodeWithTextPath(topNodePath);
except
on EInvalidPath do Path := '';
end;
{ Setting the path apparently also expands the selected node, thus re-apply
the recorded node state, but don't refresh nodes. }
//RestoreNodeState(node, False, expandedPaths); // --- not needed (wp)
(* -- not needed (wp)
{ Force synchronization of associated ShellListView }
if Assigned(FShellListView) then
begin
fileList := FShellListView;
ShellListView := nil;
ShellListView := fileList;
ShellListView.Selected := ShellListView.FindCaption(0, selectedFile, false, true, false);
end;
*)
finally
Items.EndUpdate;
expandedPaths.Free;
end;
end;