Quick Tips: Trabalhando com Objeto no TreeView

Você precisa estar logado para dar um feedback. Clique aqui para efetuar o login
Para efetuar o download você precisa estar logado. Clique aqui para efetuar o login
Confirmar voto
0
 (3)  (0)

Nesta Quick iremos ver como trabalhar com Objetos no TreeView

Olá galera, nesta Quick Tips mostrarei um componente no Delphi chamado TreeView. Veremos que neste componente não trabalhamos somente com textos adicionados a ele, formando aquela árvore, mas também adicionar um objeto inteiro, uma classe Cliente por exemplo, sendo o nó principal, e os telefones sendo seus nós filhos. Criaremos a aplicação e duas classes, sendo uma delas usando uma lista genérica, o famoso Generics, a partir do Delphi 2009.

Vamos ao exemplo! Adicione os itens a seguir, conforme a Figura 1:

  • 1 TreeView.
  • Cliente : 3 Bitbtns(BtnAdicionar, BtnEditar, BtnDeletar), 3LabeledEdit(EdtCodigo, EdtNome, EdtCPF).
  • Telefone : 2 Bitbtns(BtnAddTelefone, BtnDelTelefone), 2LabeledEdit(EdtDDD, EdtNumero) 1 Combobox(CbxTipo) e 1 Label.
Itens do formulário
Figura 1. Itens do formulário

Iremos criar agora uma nova Unit - salve a mesma como uTelefone.Esta class será bem simples, porém com ela poderemos ver um recurso muito poderoso englobado no Delphi 2009 em diante, chamado Generics. Utilize o código a seguir:

uTelefone
  
 unit uTelefone;
  
 interface
 Type
   TTelefone = Class
   private
     FDDD: String;
     FNumero: String;
     FTipo: String;
     procedure SetDDD(const Value: String);
     procedure SetNumero(const Value: String);
     procedure SetTipo(const Value: String);
   published
   public
     property DDD    : String read FDDD write SetDDD;
     property Numero : String read FNumero write SetNumero;
     property Tipo   : String read FTipo write SetTipo;
   End;
  
 implementation
  
 { TTelefone }
  
 procedure TTelefone.SetDDD(const Value: String);
 begin
   FDDD := Value;
 end;
  
 procedure TTelefone.SetNumero(const Value: String);
 begin
   FNumero := Value;
 end;
  
 procedure TTelefone.SetTipo(const Value: String);
 begin
   FTipo := Value;
 end;
  
 end.

Criaremos agora uma nova Unit e salve a mesma como uCliente.Nesta Unit observe que demos Uses em generics.defaults e generics.collections para podermos usar o Generics. Assim temos uma lista de Telefones para cada cliente, ou seja, um telefone pode ter um ou mais clientes. Com o código a seguir observe também que é bem simples excluir um telefone desta lista:

uCliente
  
 unit uCliente;
  
 interface
 uses generics.defaults, generics.collections, uTelefone;
 Type
   TCliente  = Class
   private
     FCodigo: Integer;
     FCPF: String;
     FNome: String;
     FTelefones: TList;
     procedure SetCodigo(const Value: Integer);
     procedure SetCPF(const Value: String);
     procedure SetNome(const Value: String);
     procedure SetTelefones(const Value: TList);
   published
   public
     Constructor Create;
     property Codigo   : Integer read FCodigo write SetCodigo;
     property Nome     : String read FNome write SetNome;
     property CPF      : String read FCPF write SetCPF;
     property Telefones: TList read FTelefones write SetTelefones;
   End;
  
 implementation
  
 { TCliente }
  
 constructor TCliente.Create;
 begin
   //Finalidade : Ao criar um Cliente já teremos a lista de telefones criadas
   Telefones := TList.Create; 
 end;
  
 procedure TCliente.SetCodigo(const Value: Integer);
 begin
   FCodigo := Value;
 end;
  
 procedure TCliente.SetCPF(const Value: String);
 begin
   FCPF := Value;
 end;
  
 procedure TCliente.SetNome(const Value: String);
 begin
   FNome := Value;
 end;
  
 procedure TCliente.SetTelefones(const Value: TList);
 begin
   FTelefones := Value;
 end;
  
 end.

Implementações no Form

A parte da manipulação do Cliente pode ser vista com o código a seguir:

    //Form : OnCreate
    //Form: onClose
    //Declare duas procedures, ClearCliente e ClearTelefone.

    procedure TFrmPrincipal.ClearCliente;
  begin
    {Finalidade : Limpar os Edits do Cliente}
    EdtCodigo.Clear;
    EdtNome.Clear;
    EdtCPF.Clear;
    EdtCodigo.SetFocus;
  end;

    procedure TFrmPrincipal.ClearTelefone;
  begin
    {Finalidade : Limpar os Edits e Combobox do Telefone}
    EdtDDD.Clear;
    EdtNumero.Clear;
    CbxTipo.ItemIndex := -1;
    EdtDDD.SetFocus;
  end;

    procedure TFrmPrincipal.FormCreate(Sender: TObject);
  begin
    TreeView1.HideSelection := False; //Destaca o item selecionado no ListView
  end;

procedure TFrmPrincipal.FormClose(Sender: TObject; var Action: TCloseAction);
var
  I: Integer;
  c: TCliente;
begin
  for I := 0 to TreeView1.Items.Count-1 do
  begin
    if TreeView1.Items[I].Level=0 then  //Exclui só a classe cliente que o resto será destruído, com isso evitamos o erro de MemoryLeak.
    begin
      c:=TreeView1.Items[I].Data;
      c.Free;
    end;
  end;

end;


    //BtnAdicionar : OnClick
    //Finalidade : Criar um cliente, atribuir os valores a suas propriedades e logo
   // em seguida adicionarmos sua referência a TreeView
  procedure TFrmPrincipal.BtnAdicionarClick(Sender: TObject);
  Var
    Cliente : TCliente;
  begin
    Cliente := TCliente.Create;
   
    With Cliente do
    begin
      Codigo := StrToInt(EdtCodigo.Text);
      Nome   := EdtNome.Text;
      CPF    := EdtCPF.Text;
    end;
   
    TreeView1.Items.AddObject(Nil,Cliente.Nome,Cliente);
    ClearCliente;
  end;

    //BtnEditar : OnClick
    //Finalidade : Ao Carregar os dados podemos editar as informações de um Objeto 
   //selecionado, porém precisamos implementar
   //o método que irá carregar, vamos ver na última parte desta série de Quick Tips.
    procedure TFrmPrincipal.BtnEditarClick(Sender: TObject);
  begin
    if Assigned(TreeView1.Selected) then //Verifica se existe referencia no item selecionado
    begin
      TCliente(TreeView1.Selected.Data).Codigo := StrToInt( EdtCodigo.Text );
      TCliente(TreeView1.Selected.Data).Nome   := EdtNome.Text;
      TCliente(TreeView1.Selected.Data).CPF    := EdtCPF.Text;
      TreeView1.Selected.Text                  := EdtNome.Text;
    end;
  end;

    //BtnDeletar : OnClick
    //Finalidade : Excluir um Objeto Cliente da TreeView, e removendo a referencia
   
  procedure TFrmPrincipal.BtnDeletarClick(Sender: TObject);
  begin
    if Assigned(TreeView1.Selected) then 
    //Verifica se existe referencia no item selecionado
    begin
      if TreeView1.Selected.Level = 0 then
       //Verifica se estamos no primeiro nível para poder deletar
      begin
         TreeView1.Selected.Data := Nil;
         TreeView1.Items.Delete(TreeView1.Selected);
      end;
    end
    else
      ShowMessage('Nenhum item selecionado');
  end;

Já os códigos a seguir cuidam das implementações no Form: a parte da manipulação do Telefone e a recuperação dos dados no TreeView.

  
//BtnAddTelefone : OnClick
  //Finalidade : Adicionar um telefone ao cliente selecionado
  procedure TFrmPrincipal.BtnAddTelefoneClick(Sender: TObject);
 Var
   Node    : TTreeNode;
   Cliente : TCliente;
   Telefone : TTelefone;
 begin
   if Assigned(TreeView1.Selected) then
   begin
     if TreeView1.Selected.Level = 0 then //Verifica se estamos no primeiro Item
     begin
       Node     := TreeView1.Selected;
       Cliente  := TCliente(TreeView1.Selected.Data);
       Telefone := TTelefone.Create;
       With Telefone do
       begin
         DDD    := EdtDDD.Text;
         Numero := EdtNumero.Text;
         Tipo   := CbxTipo.Text;
       end; 

       Cliente.Telefones.Add(Telefone);
       TreeView1.Items.AddChildObject(Node,Telefone.Numero, Cliente);
       ClearTelefone;
     end
     else
       ShowMessage('Não trabalhamos com mais de um Nivel de Node');
   end
   else
     ShowMessage('Erro !!! Não existe um Node Pai Selecionado');
 end;


  //BtnDelTelefone :  OnClick
  //Finalidade : Excluir um telefone de um Cliente
  procedure TFrmPrincipal.BtnDelTelefoneClick(Sender: TObject);
 begin
   if Assigned(TreeView1.Selected) then
     //Verifica se existe referencia no item selecionado
   begin
     if TreeView1.Selected.Level = 1 then 
       //Verifica se estamos no segundo nível para poder deletar
     begin
        TCliente(TreeView1.Selected.Data).Telefones.Delete(TreeView1.Selected.Index);
        TreeView1.Selected.Delete;
     end;
   end;
 end;

   //TreeView : OnClick
  //Finalidade : Carregar para o Form as informações armazenadas no 
  //TreeView, permitindo exclusão ou alteração. 
 

procedure TFrmPrincipal.TreeView1Click(Sender: TObject);
begin
  ClearCliente;
  ClearTelefone;

  if TreeView1.Selected.Level = 0 then //Verifica se estamos no primeiro nível
  begin
    EdtCodigo.Text := IntToStr( TCliente(TreeView1.Selected.Data).Codigo );
    EdtNome.Text   := TCliente(TreeView1.Selected.Data).Nome;
    EdtCPF.Text    := TCliente(TreeView1.Selected.Data).CPF;
  end
  else
  if TreeView1.Selected.Level = 1 then //Verifica se estamos no segundo nível
  begin
    EdtCodigo.Text    := IntToStr( TCliente(TreeView1.Selected.Data).Codigo );
    EdtNome.Text      := TCliente(TreeView1.Selected.Data).Nome;
    EdtCPF.Text       := TCliente(TreeView1.Selected.Data).CPF;

    EdtDDD.Text       := TCliente(TreeView1.Selected.Data).Telefones[TreeView1.Selected.Index].DDD;
    EdtNumero.Text    := TCliente(TreeView1.Selected.Data).Telefones[TreeView1.Selected.Index].Numero;
    CbxTipo.ItemIndex := CbxTipo.Items.IndexOf(TCliente(TreeView1.Selected.Data).Telefones[TreeView1.Selected.Index].Tipo);
  end;
end;

Testando o exemplo

Testando a aplicação

Fico por aqui e na próxima Quick Tips.

 
Você precisa estar logado para dar um feedback. Clique aqui para efetuar o login
Receba nossas novidades
Ficou com alguma dúvida?