2

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;

これは、マウスとシフト キーを使用する場合は問題なく動作しますが、キーボードを使用する場合、つまりノードを選択し、シフト キーを押してから下矢印キーを押して複数のノードを選択すると、選択によって完全なリスト - 1 が返されます。

これはバグのようですか?キーボードを使用するときに完全な選択を取得する方法についてのアイデアはありますか?

4

2 に答える 2

3

この動作も再現できます (D5、VT ver 4.5.5)。私にはバグのように見えます。その理由を説明します。

キーボードイベントが呼び出されるようですが、イベントがトリガーされた時点でFocusChanged内部は変更されません。のコードを見ると、最初の行はであり、プロパティをテストすると、実際の選択カウント - 1 (説明どおり) に設定されるか、SHIFT-END を押すと、の値が残ります。FSelectedCountFocusChangedGetSortedSelectionSetLength(Result, FSelectionCount);VST1.SelectionCount

PostMessageこの特定のイベントで遅延アクションを使用しているため、自分のアプリでこれに気付いたことはありません。これにより、イベント ハンドラーが終了したときに正しい内部構造が得られます。これは1つの解決策になる可能性があります。

ただし、正しい方法であると私が信じる適切な解決策は、OnChangeイベントハンドラーで選択を処理することです。選択は、フォーカスノードの変更に関係なく変更される可能性があります。

于 2016-10-31T17:39:19.117 に答える
1

選択の変更を追跡するためのイベントがあります。OnAddToSelectionイベントの代わりにこれらを使用する必要があります。OnRemoveFromSelectionOnFocusChanged

簡単なテストを行ったところOnAddToSelectionGetSortedSelectionメソッドが起動すると、既に選択されているノードの配列と、選択される (または選択に追加される) ノードがNode引数として返されるようです。

OnRemoveFromSelection起動すると、GetSortedSelectionメソッドは選択されたノードの配列を返し、Nodeパラメータは選択から削除されるノードです。したがって、イベントは完全に「対称的」ではないと言えます。

GetSortedSelectionメソッドがOnRemoveFromSelectionアプリで実際に使用されると、終了時に AV が発生します。これはVTのバグだと思います。VT.OnRemoveFromSelection := nil;フォームのハンドラーで設定OnDestroyすると修正されるようです...解決策があるように見えるので、これ以上調査しませんでした。

于 2016-10-31T17:14:07.587 に答える