Is there a built-in way to always select node?
Yes there is. Remove the code from these events and enable the toAlwaysSelectNode option in the TreeOptions.SelectionOptions tree setting (for example, enable it in the IDE). A comment on this option says:
If this flag is set to true, the tree tries to always have a node selected.
Including the removal of node.
How to safely update management status controlled by external management from a VT event?
The problem you are facing is that you focused the node manually from the OnFreeNode event, which in turn raised the OnFocusChanged event. And since nodes are also freed when the control is destroyed and this button was destroyed earlier, you are trying to access the destroyed control. To avoid this in the future, you can use RTL actions because there are many events that VT fires, even when it has csDestroying state (including an event like OnStructureChange ), and actions are one safe workaround.
Something like this should work safely (I'm not a fan of the OnUpdate event):
procedure TMyForm.VSTStructureChange(Sender: TBaseVirtualTree; Node: PVirtualNode; Reason: TChangeReason); begin { ActionDeleteNode is assigned to the button Action property; SelectedCount is a bit paranoic here because if you use the toAlwaysSelectNode option, at least one node should be always selected, so RootNodeCount > 0 could do the same here } ActionDeleteNode.Enabled := Sender.SelectedCount > 0; end;
Without RTL actions, you can safely update this button state, for example. immediately after the action, for example, after removing the node:
VST.DeleteNode(VST.FocusedNode); ButtonDeleteNode.Enabled := VST.SelectedCount > 0;
But with this, you can get out of sync and write more code. Therefore, using RTL actions is what I would prefer.
Victoria
source share