TreeView no Delphi


Vamos para um exemplo de TreeView no Delphi, neste exemplo vamos fazer um TreeView de plano de contas, com os níveis de Filho e Pai e exibir imagem no componente.

Vamos precisar de:
  • DBGrid: TDBGrid;
  • tvPlanos: TTreeView;
  • dsPlanos: TDataSource;
  • BtnGerar: TBitBtn;
  • BtnExpandir: TBitBtn;
  • BtnRecolher: TBitBtn;
  • ImageList1: TImageList;
  • cdsPlanos: TClientDataSet;

Com esses campos em tela vamos colocar eles disposto da seguinte forma:

Reparem que a coluna "Pai" esta recebendo o código do plano de contas que serio o pai da determinada conta! 

Vamos colocar um botão para a geração de nossa "Arvore", renomeamos esse botão para BtnGerar e colocar o código abaixo:
procedure TFSistema.BtnGerarClick(Sender: TObject);
var
  lNoPai: TTreeNode;
begin
  cdsPlanos.Filter := 'PAI = 0';
  cdsPlanos.Filtered := True;
  cdsPlanos.First;
  while not cdsPlanos.Eof do begin
    if cdsPlanos.FieldByName('PAI').AsInteger = 0 then begin
      lNoPai := tvPlanos.Items.Add(nil, cdsPlanos.FieldByName('DESCRICAO').AsString);
      AdicionarFilho(cdsPlanos.FieldByName('CODIGO').AsInteger, lNoPai);
    end;
    cdsPlanos.Next;
  end;
  cdsPlanos.Filtered := False;
end;

No código acima estamos fazendo um filtro para selecionar apenas o "Pai" dos planos de conta, e passando isto para um laço de repetição que contem a procedure "AdicionarFilho" para adicionar os filhos das mesmas, abaixo o código da procedure "AdicionarFilho".
procedure TFSistema.AdicionarFilho(const aPai: integer; const aNoPai: TTreeNode);
var
  lcdsAuxiliar: TClientDataSet;
  lNoFilho: TTreeNode;
begin
  lcdsAuxiliar := TClientDataSet.Create(nil);
  try
    lcdsAuxiliar.CloneCursor(cdsPlanos, True);
    lcdsAuxiliar.Filter := 'PAI = ' + IntToStr(aPai);
    lcdsAuxiliar.Filtered := True;
    while not (lcdsAuxiliar.Eof) do begin
      lNoFilho := TTreeNode.Create(nil);
      lNoFilho := tvPlanos.Items.AddChild(aNoPai, lcdsAuxiliar.FieldByName('DESCRICAO').AsString);
      tvPlanos.Items[tvPlanos.Items.Count - 1].ImageIndex := 1;
      AdicionarFilho(lcdsAuxiliar.FieldByName('CODIGO').AsInteger, lNoFilho);
      lcdsAuxiliar.Next;
    end;
  finally
    FreeAndNil(lcdsAuxiliar);
  end;
end;

No código acima estamos clonando nossa tabela principal e fazendo o filtro de apenas os filhos de um determinado "Pai", e novamente um laço de repetição para cadastrar todos os filhos vinculados!

Para expandir todos os itens utilizamos o código abaixo:
procedure TFSistema.BtnExpandirClick(Sender: TObject);
begin
  tvPlanos.FullExpand;
end;

Para recolher todos os itens utilizamos o código abaixo:
procedure TFSistema.BtnRecolherClick(Sender: TObject);
begin
  tvPlanos.FullCollapse;
end;

Ao final do processo ficara assim:

6 comentários:

  1. Por favor, como acrescentamos um nó neto a um nó filho?

    ResponderExcluir
  2. Muito obrigado por compartilhar o conhecimento.

    Fiz um exemplo seguindo seus passos e no meu apresentou Memory Leak.
    Realizando alguns testes, percebi que retirando a linha de código (lNoFilho := TTreeNode.Create(nil);) da procedure "AdicionarFilho" não apresentou mais o problema e funcionou normalmente.

    ResponderExcluir
  3. Muito Legal.. Daria para fazer Essa mesma Lógica de Clonar, Utilizando ZTable? Não encontrei como fazer aqui

    ResponderExcluir
  4. Precisava urgente de um exemplo de Plano de Contas Feito em Delphi, Nunca fiz e não sei nem por onde começar

    ResponderExcluir
  5. o link do dowloand ta quebrado, tem como mandar de novo?

    ResponderExcluir
  6. Poderia por favor Disponibilizar o exemplo para estudos ... link quebrado.

    ResponderExcluir