我启用了带有MultiSelect选项的VST。当选择通过键盘事件更改时,如何在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?关于如何在使用键盘时获得完整选择的任何想法?
答案 0 :(得分:2)
我也可以重现这种行为(D5,VT ver 4.5.5)。对我来说看起来像个错误,我会解释原因:
似乎键盘事件调用FocusChanged
但在触发FSelectedCount
事件时不会更改内部FocusChanged
。如果您查看GetSortedSelection
的代码,第一行是SetLength(Result, FSelectionCount);
,如果您测试VST1.SelectionCount
属性,则将其设置为实际选择计数 - 1(如您所述)或者如果您按SHIFT-END,上一个值仍然存在。
我在自己的应用中从未注意到这一点,因为我在此特定事件中通过PostMessage
使用了延迟操作。这会在事件处理程序退出时产生正确的内部结构。这可能是一个解决方案。
然而,我认为正确的解决办法是在OnChange
事件处理程序中处理选择 - 无论焦点节点如何变化,选择都可能发生变化。
答案 1 :(得分:1)
有OnAddToSelection
和OnRemoveFromSelection
个事件用于跟踪选择中的更改,我认为您应该使用这些事件代替OnFocusChanged
事件。
进行了快速测试,似乎当OnAddToSelection
触发GetSortedSelection
方法时,返回已选择的节点数组以及要选择(或添加到选择中)的节点为{{1} }参数。
当Node
触发时,OnRemoveFromSelection
方法返回所选节点的数组,GetSortedSelection
参数是即将从选择中删除的节点。所以你可以说这些事件不是“对称的”。
在Node
中使用GetSortedSelection
方法时,应用确实会退出AV。我会说这是VT中的一个错误。在表单的OnRemoveFromSelection
处理程序中设置VT.OnRemoveFromSelection := nil;
似乎可以解决这个问题......因为您似乎有解决方案我没有进一步调查。