我有VST与MultiSelect选项启用。当选择通过键盘事件改变时,我如何检索VirtualStringTree中选定节点的列表?
我尝试在OnFocusChanged事件
中使用以下代码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;
如果我使用鼠标和shift键,这工作得很好,但是,如果我使用键盘,即选择节点,然后按shift键,然后向下箭头选择多个节点,选择返回完整的列表- 1。
这看起来像一个bug?在使用键盘时如何获得完整的选择有什么想法吗?
我也可以重现这个行为(D5, v4.5.5)。在我看来像是一个bug,我将解释原因:
似乎键盘事件(s)调用FocusChanged
,但在触发FocusChanged
事件时不改变内部FSelectedCount
。如果您查看GetSortedSelection
的代码,第一行是SetLength(Result, FSelectionCount);
,如果您测试VST1.SelectionCount
属性,它被设置为实际的选择计数- 1(如您所描述的),或者如果您按SHIFT-END,则前面的值保留。
我从来没有在我自己的应用程序中注意到这一点,因为我在这个特定的事件中通过PostMessage
使用延迟动作。这将在事件处理程序退出时产生正确的内部消息。这可能是一个解决方案。
然而,我认为正确的解决方案是在OnChange
事件处理程序中处理选择-无论焦点节点更改,选择都可以更改
有OnAddToSelection
和OnRemoveFromSelection
事件是为了跟踪选择的变化,我猜你应该使用这些而不是OnFocusChanged
事件。
做了一个快速测试,似乎当OnAddToSelection
触发GetSortedSelection
方法返回已经选择的节点数组和要选择的节点(或添加到选择中)作为Node
参数。
当OnRemoveFromSelection
触发时,GetSortedSelection
方法返回所选节点的数组,Node
参数是即将从选择中删除的节点。所以你可以说这些事件不是完全"对称的"。
当GetSortedSelection
方法在OnRemoveFromSelection
中使用时,应用程序确实在退出时av。我想说这是VT的一个bug,在form的OnDestroy
处理程序中设置VT.OnRemoveFromSelection := nil;
似乎可以修复它…既然你似乎已经有了解决办法,我就不再深入调查了。