Reputation: 3481
I have VST with MultiSelect option enabled. How can I retrieve the list of selected nodes in VirtualStringTree when the selection changes via keyboard events?
I tried using the below code in the OnFocusChanged event
procedure TForm1.UpdateSelection(VST: TVirtualStringTree);
Var
NodeArray: TNodeArray;
NodeData: PNodeData;
I: Integer;
begin
Memo1.Clear;
NodeArray := VST.GetSortedSelection(False);
For I := Low(NodeArray) to High(NodeArray) do
Begin
NodeData := VST.GetNodeData(NodeArray[I]);
Memo1.Lines.Add(NodeData.Caption);
End;
end;
procedure TForm1.VST1FocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode;
Column: TColumnIndex);
begin
UpdateSelection(VST1);
end;
This works fine if I use the mouse and shift key, however, if I use the keyboard, i.e select node, then press shift and then down arrow to select multiple nodes, the selection returns the full list - 1.
This seems like a bug? Any ideas on how to get the full selection when using the keyboard?
Upvotes: 2
Views: 3844
Reputation: 22749
There are OnAddToSelection
and OnRemoveFromSelection
events which are meant to track changes in selection, I quess you should use these instead of OnFocusChanged
event.
Did a quick test and it seems that when OnAddToSelection
fires the GetSortedSelection
method returns the array of nodes already selected and the node to be selected (or added to the selection) as Node
argument.
When OnRemoveFromSelection
fires the GetSortedSelection
method returns the array of selected nodes and Node
parameter is the node about to be removed from the selection. So you could say that the events are not competely "symmetrical".
When GetSortedSelection
method is used in OnRemoveFromSelection
the app indeed AVs on exit. I would say this is a bug in VT. Seting VT.OnRemoveFromSelection := nil;
in form's OnDestroy
handler seems to fix it... as you seem to have your solution I didn't investigate any further.
Upvotes: 1
Reputation: 21242
I can also reproduce this behavior (D5, VT ver 4.5.5). looks like a bug to me, and I'll explain why:
Seems like the keyboard event(s) calls FocusChanged
but does not change the internal FSelectedCount
at the moment FocusChanged
event is triggered. if you look at the code of GetSortedSelection
, the first line is SetLength(Result, FSelectionCount);
and if you test VST1.SelectionCount
property it is set to the actual selection count - 1 (as you describe) or if you press SHIFT-END the previous value remains.
I have never noticed this in my own app because I use a delayed action via PostMessage
in this specific event. this results the correct internals when the event handler exits. this could be one solution.
However, the proper solution which I believe is the correct way, is to handle the selection in the OnChange
event handler - the selection could be change regardless of a focus node change.
Upvotes: 3