如何在选择更改后检索VirtualStringTree中的选定节点?

时间:2016-10-31 15:58:51

标签: delphi virtualtreeview tvirtualstringtree

我启用了带有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?关于如何在使用键盘时获得完整选择的任何想法?

2 个答案:

答案 0 :(得分:2)

我也可以重现这种行为(D5,VT ver 4.5.5)。对我来说看起来像个错误,我会解释原因:

似乎键盘事件调用FocusChanged但在触发FSelectedCount事件时不会更改内部FocusChanged。如果您查看GetSortedSelection的代码,第一行是SetLength(Result, FSelectionCount);,如果您测试VST1.SelectionCount属性,则将其设置为实际选择计数 - 1(如您所述)或者如果您按SHIFT-END,上一个值仍然存在。

我在自己的应用中从未注意到这一点,因为我在此特定事件中通过PostMessage使用了延迟操作。这会在事件处理程序退出时产生正确的内部结构。这可能是一个解决方案。

然而,我认为正确的解决办法是在OnChange事件处理程序中处理选择 - 无论焦点节点如何变化,选择都可能发生变化。

答案 1 :(得分:1)

OnAddToSelectionOnRemoveFromSelection个事件用于跟踪选择中的更改,我认为您应该使用这些事件代替OnFocusChanged事件。

进行了快速测试,似乎当OnAddToSelection触发GetSortedSelection方法时,返回已选择的节点数组以及要选择(或添加到选择中)的节点为{{1} }参数。

Node触发时,OnRemoveFromSelection方法返回所选节点的数组,GetSortedSelection参数是即将从选择中删除的节点。所以你可以说这些事件不是“对称的”。

Node中使用GetSortedSelection方法时,应用确实会退出AV。我会说这是VT中的一个错误。在表单的OnRemoveFromSelection处理程序中设置VT.OnRemoveFromSelection := nil;似乎可以解决这个问题......因为您似乎有解决方案我没有进一步调查。