Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Поиск в VirtualTreeView


Автор: MacTep 15.8.2012, 16:18
Осуществляю поиск узла дерева VirtualTreeView следующей процедурой:
Код

// поиск узла дерева
function TfrmTrainingList.FindNode(ANode: PVirtualNode; const APattern: integer): PVirtualNode;
var NextNode: PVirtualNode;
    DataNode: PTrainingNode;
begin
  Result := nil;
  NextNode := ANode.FirstChild;
  if Assigned(NextNode) then
  begin
    repeat
      DataNode := vt.GetNodeData(NextNode);
      if Assigned(DataNode) then
        if DataNode^.training_id = APattern then
        begin
          Result := NextNode;
          exit;
        end;
      // Ищем в дочерних ветках
      Result := FindNode(NextNode, APattern);
      if Result = nil then
        NextNode := NextNode.NextSibling
      else
      begin
        NextNode := nil;
        break;
      end;
    until NextNode = nil;
  end;
end;
Все хорошо работает, если дерево без дочерних элементов, т.е. дерево обычный список.
Если же в дереве есть дочерние элементы, а в них есть еще дочерние элементы, то нужный элемент не находится. Возвращается nil.

Помогите исправить ошибку.

Автор: XperT 15.8.2012, 17:15
Как то так (не проверял):
Код

function TfrmTrainingList.FindNode(const APattern: integer): PVirtualNode;
var 
    ANode: PVirtualNode;
    DataNode: PTrainingNode;
begin
  Result := nil;
  ANode := vt.GetFirst();
  while ANode <> nil do
  begin
    DataNode := vt.GetNodeData(ANode);
    if (Assigned(DataNode)) and (DataNode^.training_id = APattern) then
    begin
      Result := ANode;
      exit;
    end;

    ANode := vt.GetNext(ANode);
  end;
end;

Автор: kami 15.8.2012, 18:50
Если нодов более чем много, и/или нужно действительно организовать поиск только в дочерних по отношению к заданному нодах, то так:
Код

Result:=nil;
NextNode:=vt.GetNextSibling(ANode); // это следующий нод того же уровня, что и стартовый. Соответственно, поиск должен вестись до него (исключительно)
ANode:=vt.GetFirstChild(ANode);
While Assigned(ANode) and (ANode<>NextNode) do
  begin
    NodeData:=vt.GetNodeData(ANode);
    if ......... then
      begin
        Result:=ANode;
        Break;
      end;
    ANode:=vt.GetNext(ANode);
  end;

Автор: MacTep 15.8.2012, 22:52
Спасибо! Оба ответа помогли внести ясность в мои мысли по этому вопросу smile

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)