Wrong management of Vertical ScrollBar
Hi, I'm using latest version of VT ( 015ebe5769102ae67092bc4dd68186e38f753fc4 ) and I've noticed that vertical scrollbar does not works fine when I expand some node, but also when all nodes are expanded and I resize the tree view control.
https://github.com/user-attachments/assets/3a4c0657-1efa-431d-83e8-0dbeff590a0a
Seems that calculated size of tree is not valid.
At frame create the main root nodes are created:
type
PTreeData = ^TTreeData;
TTreeData = record
UID: TGUID;
end;
constructor TVMSetupFrame.Create(AOwner: TComponent);
procedure CreateTreeViewStructure;
function AddNode(PartType: TMachinePartType): PVirtualNode;
var
NodeData: PTreeData;
begin
Result := TreeView.AddChild(nil);
NodeData := TreeView.GetNodeData(Result);
NodeData.UID := GetVMManager.MachinePartsList.Parts[PartType, 0].PartUID;
end;
begin
TreeView.NodeDataSize := SizeOf(TTreeData);
FRootNodeF := AddNode(mptp_FixedRoot);
FRootNodeX := AddNode(mptp_AxisXRoot);
FRootNodeY := AddNode(mptp_AxisYRoot);
FRootNodeZ := AddNode(mptp_AxisZRoot);
FRootNodeM := AddNode(mptp_MasterRoot);
FRootNodeS := AddNode(mptp_SlaveRoot);
end;
begin
// creates tree view structure
CreateTreeViewStructure;
....
..
....
// updates tree
UpdateTree;
// selects first node
TreeView.Selected[FRootNodeF] := True;
end;
procedure TVMSetupFrame.UpdateTree;
procedure UpdateNodes(Parent: PVirtualNode; PartType: TMachinePartType);
var
I: Integer;
C: Integer;
Child: PVirtualNode;
NodeData: PTreeData;
begin
C := GetVMManager.MachinePartsList.Count[PartType];
for I := Parent.ChildCount to C - 1 do
TreeView.AddChild(Parent);
for I := Parent.ChildCount downto C + 1 do
TreeView.DeleteNode(Parent.LastChild);
if Parent.ChildCount > 0 then
begin
Child := nil;
for I := 0 to Parent.ChildCount - 1 do
begin
if I = 0 then
Child := Parent.FirstChild
else
begin
if Child = nil then Exit;
Child := Child.NextSibling;
end;
if Child = nil then Exit;
NodeData := TreeView.GetNodeData(Child);
NodeData.UID := GetVMManager.MachinePartsList.Parts[PartType, I].PartUID;
end;
end;
end;
begin
TreeView.BeginUpdate;
try
UpdateNodes(FRootNodeF, mptp_Fixed);
UpdateNodes(FRootNodeX, mptp_AxisX);
UpdateNodes(FRootNodeY, mptp_AxisY);
UpdateNodes(FRootNodeZ, mptp_AxisZ);
UpdateNodes(FRootNodeM, mptp_Master);
UpdateNodes(FRootNodeS, mptp_Slave);
finally
TreeView.EndUpdate;
end;
end;
Please respect our guidelines on the project homepage for submitting bugs. Please include your version of Delphi, and attach a sample compiling project as ZIP to your report that allows to replicate the problem. If only small changes are required, a description is sufficient how a demo projects needs to be changed in order to replicate the bug. If you already have a solution, please supply a patch file.
There are known problems with the vertical scrollbar when using hidden nodes (#1257) and changing the font size (#1183). Could yours be related?
I'm using Delphi 12 Update 3 (latest available version). I next days I will prepare a little project to replicate the issue. PS: sorry I've searched the post rules but not find them.
Faced the same similar problem Delphi 12.3, the latest version of VST
I was not able to replicate the behaviour in as simple project, because the actual use is very complex. However I found a workaround. I update dinamically the children nodes and if I remove the BeginUpdate and EndUpdate from the nodes update all works fine:
procedure TVMSetupFrame.UpdateTree;
procedure UpdateNodes(Parent: PVirtualNode; PartType: TMachinePartType);
var
I: Integer;
C: Integer;
Child: PVirtualNode;
NodeData: PTreeData;
begin
C := GetVMManager.MachinePartsList.Count[PartType];
for I := Parent.ChildCount to C - 1 do
TreeView.AddChild(Parent);
for I := Parent.ChildCount downto C + 1 do
TreeView.DeleteNode(Parent.LastChild);
if Parent.ChildCount > 0 then
begin
Child := nil;
for I := 0 to Parent.ChildCount - 1 do
begin
if I = 0 then
Child := Parent.FirstChild
else
begin
if Child = nil then Exit;
Child := Child.NextSibling;
end;
if Child = nil then Exit;
NodeData := TreeView.GetNodeData(Child);
NodeData.UID := GetVMManager.MachinePartsList.Parts[PartType, I].PartUID;
end;
end;
end;
begin
{**
* TAKE CARE
* =========
* Normally, you should update the node list by inserting the code between TreeView.BeginUpdate and
* TreeView.EndUpdate, but it seems that if you use this method, the internal calculation of the tree height becomes
* incorrect and, as a result, if the list exceeds the viewable height, the value becomes incorrect and even if you
* scroll to the bottom, some of the nodes are not displayed.
**}
//TreeView.BeginUpdate;
try
UpdateNodes(FRootNodeF, mptp_Fixed);
UpdateNodes(FRootNodeX, mptp_AxisX);
UpdateNodes(FRootNodeY, mptp_AxisY);
UpdateNodes(FRootNodeZ, mptp_AxisZ);
UpdateNodes(FRootNodeM, mptp_Master);
UpdateNodes(FRootNodeS, mptp_Slave);
finally
// TreeView.EndUpdate;
end;
end;
Before (left) and after (right)
The use of BeginUpdate() and EndUpdate() delays some costly calculations that are necessary when modifying tree-nodes until the call of EndUpdate(). So maybe something isn't done correctly in this case.
The only operation that modify the instance of Virtual TreeView are the calls to AddChild() and DeleteNode(). The code seems to adust the number of child nodes to the necessary number, is this correct?
That means that either AddChild() or DeleteNode() is getting called: Can you please check if boths call are affected by the problem, or just one of them?
To adjust the number of child nodes, the call to TreeView.ChildCount[ParentNode] := C; would be easier. Does this show the same Problem?