TIWAdvTreeView Examples

Are there any examples demonstrating the use of the TIWAdvTreeView component?  I did not see anything in the help file, or the demo.  Do I have the wrong versions of those items?

I am using Delphi 2007 and IW9.  Does the component work in that environment?  I was able to place an instance on a form, but was not able to actually add items.  Is that a design-time feature?

Thanks

A TIWAdvTreeView demo is included in the IWFeaturesDemo of the IntraWeb Component Pack.


Items can be added at design-time using the AdvTreeNodes Editor dialog (double click the control or click on the Items property) or programatically.

Example:
var
  N, NC :  TAdvTreeNode;
begin

  TIWAdvTreeView1.Items.Clear;

  N := TIWAdvTreeView1.Items.Add('Folder 1');
  N.Hint := 'Folder 1';
  N.ImageURL := '/files/folder.gif';
  N.ImageCollapsedURL := '/files/folder-closed.gif';
  N.Tag := 1;
  N.IsExpanded := False;

  NC := N.AddChild('File A');
  NC.Hint := 'File A';
  NC.ImageURL := '/files/file.png';
  NC.Tag := 2;

  NC := N.AddChild('File B');
  NC.Hint := 'File B';
  NC.ImageURL := '/files/file.png';
  NC.Tag := 3;

At design time the items property shows a plus symbol to the left, but it does not expand.  It does not show ellipses either.  When I double click the control it takes me into code for an event.

Can you please check if the TMS IntraWeb Component Pack design time package was installed correctly?


For Delphi 2007 with IW9 that would be the file called "iw9tmsded2007.dpk".

I see the "TMS IntraWeb Components design time support" in the packages list.  It points to C:\Users\Public\Documents\RAD Studio\5.0\Bpl\iw9tmsded2007.bpl.  The package file is located in a different folder.


It is not clear how you managed to put the TIWAdvTreeView on the form. Did you manually modify our packages?

Normally, TIWAdvTreeView is only supported from IntraWeb 10.

No, I didn't modify any of the files.  I know better than that.  I followed the instructions in the text file contained in the zip.  Sorry to hear the tree is only available for IW10 because I'm too far into this project to switch. 

However, I am not able to compile the demo due to an error while compiling the GridExport form that reads: "File not found: UFlxFormats.dcu.  I've used your products for a long time and am very familiar with the installation process.  I could have opened the wrong package, but that usually results in far more serious errors, and it usually is not permitted by the IDE.

Should I re-install?

I double checked the package iw9tmsd2007.dpk and it has no reference to TIWAdvTreeView so it is unclear how it could have installed the treeview in the IDE.
Wrt the UFlxFormats unit, please change the unit reference to tmsiwuflxformats 

I got the demo to compile after making that change.  The TIWAdvTreeView component does appear on my pallete.  I have been able to use it in the project.  I was able to add items to it following the code you provided above.  I will take my chances to see how far I can get with it.

I'm trying to load the tree from a database table that has a parent-child relationship.  As I load the data for each node I store the record# in the Tag field.  Before adding a new node I need to know if its parent is already present so I can add the node in the right place.

I have tried searching the tree using a For loop, but that does not work with your tree as it does on the standard IW tree control.  Is there a way to search the entire tree for a specific tag value?  Is there an example of using the tree against a database?  Will this require recursion?  If so, do you have an example I can study?


- Unfortunately there are currently no samples or demos available for using the IWAdvTreeView with data from a database.

- Here is some sample code that can be used to search trough all items from an IWAdvTreeView using recursion.

    N: TAdvTreeNode;

    N := TIWAdvTreeView1.Items.GetFirstNode;
    while (N <> nil) do
    begin
      RetrieveChildNodes(N);
      N := N.getNextSibling;
    end;


function RetrieveChildNodes(Node: TAdvTreeNode): string;
var
  ExN: TAdvTreeNode;
begin
  if not Assigned(Node) then
    Exit;

  ExN := Node.getFirstChild;
  if Assigned(ExN) then
  begin
    while (ExN <> nil) do
    begin

    OutputDebugString(pchar('item tag: ' + IntToStr(ExN.Tag)));

      RetrieveChildNodes(ExN);
      ExN := ExN.getNextSibling;
    end;
  end;
end;

Yuck!  Recursion has always been unclear to me, but I use it if I have to.  Can you show me how to change that code to return the index of the item with the matching tag?  That examples appears to build a string.  I apologize for my weakness in this area, but I can make it work if you can get me that far.

All of my efforts to create a function that returns the index of the parent item have failed for various reasons.  Maybe my logic is flawed.  I have a temporary table ordered in such a way that the parent records are at the top of the list so that as I add each node the parent will already have been added.

This is where I get stuck.  I know from debugging that the parent node exists, but I cannot seem to return the correct index for that parent.  Here is a bit of the code:

ni := <call search function here to return index of the item>
if (ni > -1)  then
begin
     with TIWAdvTreeView1.Items[nid].AddChild(DownlineFullName.AsString) do
       Tag := DownlineDistributorID.AsInteger;
end
else
begin
     with TIWAdvTreeView1.Items.Add(DownlineFullName.AsString) do
       Tag := DownlineDistributorID.AsInteger;
end;

Is this the wrong approach?

I know recursion can be confusing, but in this case I don't know of any alternative.

I would recommend using a TAdvTreeNode object instead of an index, that will make it easier to add child nodes.
Below is the modified sample code. I hope this can help you.

ParentNode: TAdvTreeNode;
ParentID: integer;

  ParentID := 1;
  ParentNode := nil;

  N := TIWAdvTreeView1.Items.GetFirstNode;

  while (N <> nil) do
  begin
    if (ParentID = N.Tag) then
      ParentNode := N;

    RetrieveChildNodes(N, ParentID);
    N := N.getNextSibling;
  end;

  if (ParentNode <> nil) then
  begin
//ParentNode.AddChild
  end
  else
  begin
      //Parent not found
  end;

procedure RetrieveChildNodes(Node: TAdvTreeNode;
  ParentID: integer);
var
  ExN: TAdvTreeNode;
begin
  if not Assigned(Node) then
    Exit;

  ExN := Node.getFirstChild;
  if Assigned(ExN) then
  begin
    while (ExN <> nil) do
    begin
      if (ParentID = ExN.Tag) then
        ParentNode := ExN;

      RetrieveChildNodes(ExN, ParentID);
      ExN := ExN.getNextSibling;
    end;
  end;
end;