2

我启用了 MultiSelect 选项的 VST。How can I retrieve the list of selected nodes in VirtualStringTree when the selection changes via keyboard events?

我尝试在 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。

这似乎是一个错误?关于如何在使用键盘时获得完整选择的任何想法?

4

2 回答 2

3

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

似乎是键盘事件调用,但在触发事件时FocusChanged不会改变内部。如果您查看 的代码,则第一行是,如果您测试属性,它将设置为实际选择计数 - 1(如您所描述),或者如果您按 SHIFT-END,则保留先前的值。FSelectedCountFocusChangedGetSortedSelectionSetLength(Result, FSelectionCount);VST1.SelectionCount

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

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

于 2016-10-31T17:39:19.117 回答
1

有些事件旨在跟踪选择的变化,我认为您应该使用这些而不是OnAddToSelection事件。OnRemoveFromSelectionOnFocusChanged

进行了快速测试,似乎在OnAddToSelection触发该GetSortedSelection方法时返回已选择的节点数组和要选择(或添加到选择中)的节点作为Node参数。

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

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

于 2016-10-31T17:14:07.587 回答