Lets say i'm using a VirtualStringTree in virtual mode.
I want to indicate that the tree has some nodes:
VirtualStringTree1.RootNodeCount := 999983;
And since this tree is in virtual mode; all the data management happens in the application and on demand.
Now sometime later i want to mark a node as selected. Something has happened in my underlying TList (at index 797977) that would cause one of the nodes (if it's visible) to need to change its selected
status.
Since everything in a virtual tree is based on Node.Index
, ideally there would be a way to indicate that an index is selected:
VirtualStringTree1.RootNodeCount := 999983;
VirtualStringTree1.Selected[797977] := True; //indicate that node at index 797977 is now selected
But the tree doesn't have an overload to set selection by index.
The only method to alter a node's selected state is to:
- a) have a
PVirtualNode
- b) pass that to
VirtualStringTree1.Selected[node] := True;
How can i mark a node as selected, when i don't have the node?
Windows ListView solution
A Windows ListView control in virtual mode solves it pretty simply.
- everything is based equivalently on
Node.Index
- and the control uses callbacks to ask the application on demand for display information
So you are given a LVN_GETDISPINFO
callback. And that is when you populate the callback structure, and give the tree the information it is asking for on demand:
- Text
- State (e.g. Selected)
- ImageIndex
- Indent
And so the way i would mark an item in the tree as Selected is i would call:
ListView1.Invalidate;
If the item #797,977 is currently on screen: it will redraw during the next paint cycle as selected.
What's the Virtual Treeivew equivalent of marking a node as Selected when all you have is a virtual-mode index?
Hack
function GetNodeByIndex(Tree: TVirtualStringTree; Index: Integer): PVirtualNode;
var
node: PVirtualNode;
begin
Result := nil;
node := Tree.GetFirstChildNoInit(nil);
while Assigned(node) do
begin
if node.Index = Index then
begin
Result := node;
Exit;
end;
node := Tree.GetNextNoInit(node);
end;
end;
But traversing a linked list of 797,977 items in order to get node n
is very bad.