delphi treeview将具有相同文本的节点放在一个节点中

时间:2018-08-21 08:09:08

标签: delphi treeview

我有此数据库表:

client1 bank1 test1 
client1 bank1 test2
client1 bank2 test1
clientx bank2 test2

我应该得到像这样的树

client1 - bank1 - test1 
                - test2
        - bank2 - test1
clientX - bank2 - test2

但是我无法按文本进行分组,而我会得到像

这样的树
  client1 - bank1 - test1 
  client1 - bank1 - test2
  client1 - bank2 - test1
  clientX - bank2 - test2

代码我有:

 repeat
        RootNode := TreeAnaliza.Items.AddObject(nil, q.FieldByName('Client').AsString, nil);    
        MiddleNode := TreeAnaliza.Items.AddChildObject(RootNode, q.FieldByName('bank').AsString, nil);    
        LowestNode:= TreeAnaliza.Items.AddChildObject(ParentNode, q.FieldByName('test').AsString, nil);
 q.Next;
 until q.Eof;

我认为我应该检查每个节点,如果在该级别上有相同文本的节点。我该如何实现?

2 个答案:

答案 0 :(得分:1)

您每次都添加一个根节点。如果客户端发生更改,则仅应添加一个根节点。中间节点也是如此。假设您的数据库按您的意愿进行了排序,那么就足够了:

RootNode := nil;
MiddleNode := nil;
repeat
  if assigned(RootNode) then
  begin
    if not SameText( RootNode.Text, q.FieldByName('Client').AsString) then
    begin
        RootNode := TreeAnaliza.Items.AddObject(nil, q.FieldByName('Client').AsString, nil);    
        MiddleNode := nil;
    end;
  end
  else
  begin
    // not assigned so definitely required
        RootNode := TreeAnaliza.Items.AddObject(nil, q.FieldByName('Client').AsString, nil);    
        MiddleNode := nil;
  end;
  if assigned( MiddleNode ) then
  begin
    if not SameText( MiddleNode.Text, q.FieldByName('bank').AsString) then
    begin
       MiddleNode := TreeAnaliza.Items.AddChildObject(RootNode, q.FieldByName('bank').AsString, nil);   
    end;
  end
  else
  begin
       MiddleNode := TreeAnaliza.Items.AddChildObject(RootNode, q.FieldByName('bank').AsString, nil);   
  end; 
        LowestNode:= TreeAnaliza.Items.AddChildObject(ParentNode, q.FieldByName('test').AsString, nil);
 q.Next;
 until q.Eof;

您可能可以整理一下。

答案 1 :(得分:1)

是的,您确实需要检查现有节点,然后才能在给定级别添加具有相同文本的新节点,例如:

function EnsureNode(ATree: TTreeView; AParent: TTreeNode; const AText: string);
var
  LNode: TTreeNode;
begin
  Result := nil;

  if AParent <> nil then
    LNode := AParent.getFirstChild
  else
    LNode := ATree.Items.GetFirstNode;

  while LNode <> nil do
  begin
    if LNode.Text = AText then
    begin
      Result := LNode;
      Exit;
    end;
  end;

  if AParent <> nil then
    Result := ATree.Items.AddChild(AParent, AText)
  else
    Result := ATree.Items.Add(nil, AText);
end;

...

while not q.Eof do
begin
  RootNode := EnsureNode(TreeAnaliza, nil, q.FieldByName('Client').AsString);

  MiddleNode := EnsureNode(TreeAnaliza, RootNode, q.FieldByName('bank').AsString);

  LowestNode := EnsureNode(TreeAnaliza, MiddleNode, q.FieldByName('test').AsString);

  q.Next;
end;

或者,使用TDictionary来跟踪已经添加的节点,例如:

var
  Dict: TDictionary<string, TTreeNode>;
  LKey, LText: string;
begin
  ...
  Dict := TDictionary<string, TTreeNode>.Create;
  try
    while not q.Eof do
    begin
      LText := q.FieldByName('Client').AsString;
      LKey := LText;
      if not Dict.TryGetValue(LKey, RootNode) then
      begin
        RootNode := TreeAnaliza.Items.Add(nil, LText);
        Dict.Add(LKey, RootNode);
      end;

      LText := q.FieldByName('bank').AsString;
      LKey := LKey + #1 + LText;
      if not Dict.TryGetValue(LKey, MiddleNode) then
      begin
        MiddleNode := TreeAnaliza.Items.AddChild(RootNode, LText);
        Dict.Add(LKey, MiddleNode);
      end;

      LText := q.FieldByName('test').AsString;
      LKey := LKey + #1 + LText;
      if not Dict.TryGetValue(LKey, LowestNode) then
      begin
        LowestNode := TreeAnaliza.Items.AddChild(MiddleNode, LText);
        Dict.Add(LKey, LowestNode);
      end;

      q.Next;
    end;
  finally
    Dict.Free;
  end;
  ...
end;