Delphi TTreeNode递归地将子节点附加到父节点

Delphi TTreeNode recursively append child nodes to parent node

我在 "project management" 有一个作业。我必须分配也可以是子模块的模块,所以我想递归地将子模块附加到模块。

示例:

P(项目)模块(M1、M2、M3、M4)。 M1模块下会有子模块(M1S1,M1S2,M1S3),子模块1(M1S1)下可以有很多子模块(M1S1S1,M1S1S2,M1S1S3)等等。

我已经使用 Recursion 和 TTreeNode 完成了这段代码,但我觉得问题出在条件语句上。

procedure TForm2.BitBtn1Click(Sender: TObject);

begin
 lGlblProjID := 1;
lGlblProjName := 'Project';
    ADOConnectionListner.Connected := true;
  try
    if ADOConnectionListner.Connected then
    begin

          RootNode := TreeView2.Items.Add(nil, lGlblProjName);
          getSubChild(lGlblProjID, RootNode);

   end;
    except
      on E: Exception do
      begin
        ShowMessage('Exception Class = ' + E.ClassName);
      end;
end;
end;

procedure TForm2.getSubChild(var Pid: Integer; var SubRoot: TTreeNode);
var
  lcount, I, lcurrentID: Integer;
  lcurrentName: String;
  lModuleNode: TTreeNode;

begin
  // ShowMessage(IntToStr(Pid)+ ' '+SubRoot.Text);

  ADOQuery1.SQL.Clear;
  ADOQuery1.SQL.Add('SELECT * FROM treetab Where parent_id =:value1');
  ADOQuery1.Parameters.ParamByName('value1').Value := Pid;
  ADOQuery1.Active := true;
  lcount := ADOQuery1.RecordCount;

  for I := 0 to lcount - 1 do
  begin
    lcurrentID := ADOQuery1.FieldByName('id').AsInteger;
    lcurrentName := ADOQuery1.FieldByName('name').AsString;
    ShowMessage(' id ' + IntToStr(lcurrentID) + ' dd ' + lcurrentName);   // print valu of i

    if ((lcurrentID <> 0)and (SubRoot.Text <> '') ) then      //or
    begin
      lModuleNode := TreeView1.Items.AddChild(SubRoot, lcurrentName);
      getSubChild(lcurrentID, lModuleNode);
    end else // if
    // lcurrentID = 0

 ShowMessage('end reached');

 //  TreeView1.Items.AddChild(SubRoot, ADOQuery1.FieldByName('name').AsString);


 ADOQuery1.Next;
    //*********
  end;

end;

我想检索特定项目的所有子模块,例如在本例中只有 id=1 的项目。

您的问题似乎是 non-local ADOQuery1,它在每次递归调用的入口处被清除。因此,您丢失了先前查询中的所有剩余记录。您应该为查询结果安排一个本地存储。

类似于(未测试):

procedure GetSubChild()
type
  TTempRecord = record
    id: integer;
    name: string;
  end;

  TTempArray = array of TTempRecord;
var
  lcount, I, lcurrentID: Integer;
  lcurrentName: String;
  lModuleNode: TTreeNode;
  recs: TTempArray
begin
  // ...
  // query the db
  // ...
  lcount := ADOQuery1.RecordCount;

  SetLength(recs, lcount);
  for i := 0 to lcount-1 do
  begin
    recs[i].id := ADOQuery1.FieldByName('id').AsInteger;
    recs[i].name := ADOQuery1.FieldByName('name').AsString;
    ADOQuery1.Next;
  end;

  for i := 0 to lcount-1 do
  begin
    lcurrentID := recs[i].id;
    lcurrentname := recs[i].name;
  // ...
  // add to treeview
  // call recursively GetSubChild()
  // ...
  end;
end;