2

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?

RaelB
  • 3,301
  • 5
  • 35
  • 55

2 Answers2

3

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.

kobik
  • 21,001
  • 4
  • 61
  • 121
  • Thanks. I also came across [this post](http://stackoverflow.com/questions/7995559/virtualtreeview-properly-handling-selection-changes?rq=1) which mentions the `OnChange` event handler, and to set the `ChangeDelay` property. Can you show how you use `PostMessage`? – RaelB Oct 31 '16 at 17:52
  • 1
    Welcome. You can look into `TForm.Release` for example and see how its implemented to get the general idea of how to use `PostMessage`. – kobik Oct 31 '16 at 18:30
1

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.

ain
  • 22,394
  • 3
  • 54
  • 74
  • nice to know about OnAddToSelection and OnRemoveFromSelection. no such event handlers in older versions. +1 – kobik Oct 31 '16 at 17:45
  • Not sure when they were introduced, I have them on VT 5.0 – ain Oct 31 '16 at 17:47
  • I would not +1 this, since I tried it and it does not solve the problem (it is actually worse), and I get an AV when I close the app. So please give more details if this actually is a solution... – RaelB Oct 31 '16 at 17:50
  • I did some of my own testing and encountered another bug: If using these events, an AV occurs just as I select all nodes with the keyboard (shift and arrow key). So it seems like it could be a possible solution, but is laden with bugs. Perhaps because people have not used it... (I tested on V5) – RaelB Oct 31 '16 at 21:28