How to populate a tree view based on a flat list with “levels”?

前端 未结 2 620
时光说笑
时光说笑 2020-12-06 13:23

I have a list of objects populated from a third-party project file. The way this file was designed is so each item is on a \"level\" of hierarchy. So the very first item is

相关标签:
2条回答
  • 2020-12-06 14:10

    Create a list that will contain the latest parent node for each level. Initially this list will be empty.

    Now walk the linear list. Whenever you add an item at level N to the list, you do the following:

    • Add it as a child of the latest parent at level N-1, and
    • set the latest parent at level N to be the item you just added.

    You'll need to handle the case where N=0 for which the above algo would require you to come up with the latest parent at level -1, whatever that means. Does your tree have an overall root node? If so, then by definition, the latest parent at level -1 is the root node. Otherwise, if there's no root node, you'll need do whatever your tree view component requires to add a node at the top level, as opposed to as a child of another node.

    Assuming that there is no root node, then the code would look like this:

    var
      Item: TItem;
      LatestParents: TList<TTreeNode>;
      Parent, NewNode: TTreeNode;
    begin
      LatestParents := TList<TTreeNode>.Create;
      try
        LatestParents.Add(nil);
        for Item in Items do
        begin
          Parent := LatestParents[Item.Level];
          NewNode := TreeView.Items.AddChild(Parent, Item.Text);
          LatestParents.Count := Max(LatestParents.Count, Item.Level+2);
          LatestParents[Item.Level+1] := NewNode;
        end;
      finally
        LatestParents.Free;
      end;
    end;
    

    You may want to put some error checking into the code if there's a possibility of your code encountering a malformed description of the tree. For instance if the first node that you encounter does not have level 0, then this code will fail.

    0 讨论(0)
  • 2020-12-06 14:12

    Try something like this:

    var
      Item: TMyItem;
      Node: TTreeNode;
      NodeLevel: Integer;
      X: Integer;
    begin
      Node := nil;
      NodeLevel := 0;
      for X := 0 to MyList.Count-1 do
      begin
        Item := MyList[X];
        if (Node = nil) or (Item.Level <= 0) then
        begin
          Node := TreeView1.Items.AddObject(nil, Item.Text, Item);
          NodeLevel := 0;
        end
        else if Item.Level = NodeLevel then
        begin
          Node := TreeView1.Items.AddObject(Node, Item.Text, Item);
        end else
        begin
          while Item.Level <= NodeLevel do
          begin
            Node := Node.Parent;
            Dec(NodeLevel);
          end;
          Node := TreeView1.Items.AddChildObject(Node, Item.Text, Item);
          Inc(NodeLevel);
        end;
        // set Node properties as needed...
      end;
    end;
    
    0 讨论(0)
提交回复
热议问题