Iterate items in AdvTreeView

Hi!

I need to iterate a treeview component to update a table with it's data.
I fill the tree like this (after creating all necessary stuff):


  while not FDQuery1.Eof do
  begin
    // ('2');
    if cl <> (FDQuery1.FieldByName('Class').AsString) then
    begin
      pn := AdvTreeView1.AddNode(tn);
      pn.Text[0] := FDQuery1.FieldByName('Class').AsString;
      pn.Extended := True;
    end;
    // ('3');
    if rn <> (FDQuery1.FieldByName('Name').AsString) then
    begin
      rt := '';
      n := AdvTreeView1.AddNode(pn);
      n.Text[0] := FDQuery1.FieldByName('Name').AsString;
      // n.DataString := FDQuery1.FieldByName('RiskName').AsString;
      n.Extended := True;
    end;
    // ('4');
    if rt <> (FDQuery1.FieldByName('Type').AsString) then
    begin
      de := '';
      subn := AdvTreeView1.AddNode(n);
      subn.Text[0] := FDQuery1.FieldByName('Type').AsString;
      subn.Extended := True;
    end;
    // ('5');
    if de <> (FDQuery1.FieldByName('Description').AsString) then
    begin
      ssubn := AdvTreeView1.AddNode(subn);
      ssubn.Text[0] := FDQuery1.FieldByName('Description').AsString;
      ssubn.Text[1] := FDQuery1.FieldByName('Effects').AsString;
      ssubn.Text[2] := FDQuery1.FieldByName('Status').AsString;
      ssubn.Extended := False;
    end;
    // ('6');
    cl := FDQuery1.FieldByName('Class').AsString;
    rn := FDQuery1.FieldByName('Name').AsString;
    rt := FDQuery1.FieldByName('Type').AsString;
    de := FDQuery1.FieldByName('Description').AsString;
    FDQuery1.Next;
  end;

After the user changes Status column I need to iterate all nodes at this level  and use ssubn.Text[0]  and ssubn.Text[1]  to update table.
I have tried with 

  lvl1 := AdvTreeView1.GetFirstRootNode;
  lvl2 := AdvTreeView1.GetFirstChildNode(lvl1);
  lvl3 := AdvTreeView1.GetFirstChildNode(lvl2);
  chld1 := AdvTreeView1.GetFirstChildNode(lvl3);
  while Assigned(chld1) do
  begin
    Memo1.Lines.Add('Child 1: ' + chld1.Text[0]);
    chld1 := chld1.GetNext;
  end;

but I also get the Type in all but the first level when I only want Description and Effects.
Any idea how to get this right?
Best Regards
Francisco Alvarado

To traverse the node tree you need to start with AdvTreeView1.GetFirstRootNode, as you did in your sample. If you want the next node on the same level, you call AdvTreeView1.GetNextSibling, and the parameter is the previous node. If you want to go down a level, you need to call AdvTreeView1.GetFirstChildNode. You can also directly call GetNextSibling on the node itself without parameters, which makes it easier to follow. Below is a sample that shows all nodes at three levels (ROOT level, sub level 1, sub level 2)




var
  n, ns, nss: TAdvTreeViewNode;
begin
  n := AdvTreeView1.GetFirstRootNode;
  //level 0 (ROOT)
  while Assigned(n) do
  begin
    OutputDebugString(pchar(n.Text[0]));
    ns := n.GetFirstChild;
    //level 1
    while Assigned(ns) do
    begin
      OutputDebugString(pchar('  '+ns.Text[0]));
      nss := ns.GetFirstChild;
      //level 2
      while Assigned(nss) do
      begin
        OutputDebugString(pchar('    '+nss.Text[0]));
        nss := nss.GetNextSibling;
      end;
      ns := ns.GetNextSibling;
    end;
    n := n.GetNextSibling;
  end;



Thank you Pieter! 

... and sorry for the delay in reading your solution.
Now I'm trying to set several advTreeView components in read-only mode based on the user's rights..
If I use enabled := False then the scroll bars are not working and the users can't see all nodes.
Is there a workaround to simulate a red-only status for the AdvTreeView?
Best Regards
Francisco Alvarado

If you mean read-only in no editing, then there is no editing available by default. If you mean also to not allow selection/interaction, but only scrolling then you can use Interaction.ReadOnly in combination with disabled selection:




procedure TForm1.AdvTreeView1BeforeSelectNode(Sender: TObject;
  ANode: TAdvTreeViewVirtualNode; var ACanSelect: Boolean);
begin
  ACanSelect := False;
end;


procedure TForm1.FormCreate(Sender: TObject);
begin
  AdvTreeView1.Interaction.ReadOnly := True;
end;

Thank you Pieter!

I decided to perform the edits defining editors in the appropriate columns so I just use this:


procedure TRskRegisterF1.AdvTreeView1BeforeOpenInplaceEditor(Sender: TObject; ANode: TAdvTreeViewVirtualNode; AColumn: Integer;
  var ACanOpen: Boolean);
begin
  ACanOpen := IsEditing;
end;