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

拈花ヽ惹草 提交于 2019-12-04 07:39:05
Remy Lebeau

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;

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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!