Как увеличить поиск с помощью TVirtualStringTree

Я учусь TVirtualStringTree использование и должны реализовать добавочный поиск. Когда пользователь вводит символы в TEdit Я хочу переместить сфокусированный узел на первый квалифицирующий узел в дереве.

Я читаю весь демо и пример кода, который я могу найти и не могу найти отправную точку для этого. Кто-нибудь может заставить меня начать с псевдокода или лучше?

2 ответа

Элемент управления уже поддерживает добавочный поиск. Вам не нужно добавлять какой-либо элемент управления для редактирования; просто начните вводить в дереве управления, и он выберет следующий соответствующий узел. Установить IncrementalSearch, IncrementalSearchDirection, IncrementalSearchStart, а также IncrementalSearchTimeout свойства по мере необходимости.

Чтобы выбрать первый узел, который соответствует заданным критериям, используйте IterateSubtree, Напишите метод, соответствующий сигнатуре TVTGetNodeProc проверить один узел по вашим критериям поиска. Он будет вызываться для каждого узла в дереве, и если узел совпадает, то он должен установить Abort параметр к истине. Используйте третий параметр IterateSubtree (названный Data) передать условие поиска в функцию обратного вызова вместе с любыми другими критериями поиска.

Я удалил часть ненужного кода, но здесь вы идете:

unit fMyForm;

interface

uses
  Windows, Messages, Forms, StdCtrls, VirtualTrees, StrUtils;

type
  TfrmMyForm = class(TForm)
    vstMyTree: TVirtualstringTree;
    myEdit: TEdit;
    procedure myEditChange(Sender: TObject);
  private
    procedure SearchForText(Sender: TBaseVirtualTree; Node: PVirtualNode; Data: Pointer; var Abort: Boolean);
  end;

  PDatastructure = ^TDatastructure;
  TDatastructure = record
    YourFieldHere : Widestring;
  end;

implementation

{$R *.dfm}

procedure TfrmMyForm.SearchForText(Sender: TBaseVirtualTree; Node: PVirtualNode; Data: Pointer; var Abort: Boolean);
var
  NodeData: PDatastructure; //replace by your record structure
begin
  NodeData := Sender.GetNodeData(Node);
  Abort := AnsiStartsStr(string(data), NodeData.YourFieldHere); //abort the search if a node with the text is found.
end;

procedure TfrmMyForm.myEditChange(Sender: TObject);
var
  foundNode : PVirtualNode;
begin
  inherited;
  //first param is your starting point. nil starts at top of tree. if you want to implement findnext
  //functionality you will need to supply the previous found node to continue from that point.
  //be sure to set the IncrementalSearchTimeout to allow users to type a few characters before starting a search.
  foundNode := vstMyTree.IterateSubtree(nil, SearchForText, pointer(myEdit.text));

  if Assigned (foundNode) then
  begin
    vstMyTree.FocusedNode := foundNode;
    vstMyTree.Selected[foundNode] := True;
  end;
end;

end.
Другие вопросы по тегам