Criando telas genéricas com TFrame em Delphi

Veja neste artigo como criar partes genéricas de telas utilizando o componente TFrame.

Acredito que um grande desafio para cada sistema que vamos desenvolver é cumprir as metas de prazos estabelecidos e muitas vezes acabamos perdendo tempo desenvolvendo telas que já criamos em outros sistemas, mas que temos que recria-las. Agora imagine podermos ter prontos determinados "pedaços" de telas para reutilizarmos em qualquer sistema? É ai que entra o componente TFrame.

Este componente pode ser encontrado em FILE > NEW > Frame.

O HELP do delphi chama ele de "TFrame is a container for components; it can be nested within forms or other frames" ou seja é um "container de componentes que pode ser usado em um ou vários form's".

Vamos para a prática. Imagine uma tela de cadastro de clientes onde é necessário cadastrar o rua, número, complemento, bairro, cidade etc..., assim:

Figura 1. Layout da tela de cadastro

Pense comigo, quando criamos telas para cadastro de fornecedores, vendedores ou outra tela que envolva cadastro de uma entidade não precisamos sempre colocar os mesmos campos de endereço? Bom para facilitar nosso trabalho e otimizar o desenvolvimento é que vamos criar um frame para endereços onde vamos conseguir inserir em qualquer form de nosso projeto ou Grupo de projetos.

Siga os passos:

  1. File > New > Frame (Insira um novo Frame, altere a propriedade NAME para FrameEndereco e salve);
  2. Após insira edit's e label's deixando ele como na figura abaixo;
  3. Se tudo estiver ok, basta abrir o form no qual você deseja inserir o frame e clicar na PALETE STANDARD EM FRAMES, selecione o frame pelo nome que você salvou e será inserido automaticamente no form.
Figura 2. Aparência do frame criado

Uma vez inserido o Frame no form, sempre que precisar acessar um valor dentro do frame é necessário primeiro indicar o nome do frame, exemplo:

FrameEndereco1.edtRua.Text:='Rua Caipos';
Listagem 1. Referenciando elementos do frame (primeira forma)

ou, se preferir,

with FrameEndereco1 do begin edtRua.Text:='Rua Caipos'; edtNumero.Text:='111' end;
Listagem 2. Referenciando elementos do frame (segunda forma)

E assim por diante.

Observação: O que for alterado no Frame se replicará em todas as telas em que ele estiver inserido.

Mas vamos imaginar algo mais complexo, imagine um ComboBox onde você precisa inserir, e excluir valores genéricos para tabelas genéricas, neste exemplo vou utilizar classes já criadas em artigos anteriores, Listas Encadeadas e Framework em Delphi. Vamos ao exemplo: Imagine um Combobox onde, em RUN TIME , seja necessário em um Form salvar e excluir o nome de cidades e em outro form o salvar e excluir o nome de vendedores. Mãos a obra então.

Siga os passos:

  1. File > New > Frame(Insira um novo Frame, altere a propriedade NAME para FrameComboGenerics e salve);
  2. Após, insira UtilComboBox(Ler artigo) e label's deixando ele como na figura abaixo;
Figura 3. Frame com Combobox de valores dinâmicos

Muto bem, agora vamos criar alguns métodos.

unit ComboGenericsFrame; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, UtilComboBox, UtilSqlSuid, UtilList; type TFrameComboGenerics = class(TFrame) edtCombo: TUtilComboBox; LbTitulo: TLabel; procedure edtComboKeyPress(Sender: TObject; var Key: Char); procedure edtComboChange(Sender: TObject); procedure edtComboContextPopup(Sender: TObject; MousePos: TPoint; var Handled: Boolean); procedure edtComboCloseUp(Sender: TObject); procedure edtComboClick(Sender: TObject); private { Private declarations } Table, Field:string; ValueId:integer; DataBase:TDataModule; public { Public declarations } //variáveis publicas que serão utilizadas para criar a //lista de dados e o componente de conexão com o banco de dados QSql:TUtilSqlSuid; QList:TUtilList; procedure CreateCombo(Table_,Field_:string;ValueId_:Integer); //create para setar o nome da tabela a ser usada, o Campo de //pesquisa e o Id do registro quando houver procedure SetTitulo(msgTitulo:string); procedure SaveCombo; //Salvar o registro inserido procedure LoadCombo; //Carregar os valores da tabela setada no CreateCombo procedure SetValue(IdValue:Integer); //Setar como default no Combo o registro que possuir o IdValue inserido function GetIdValue:Integer; //Capturar o id do registro selecionado no combo procedure ReposicionaLabel; end;
Listagem 3. Código do frame criado

Muito bem, uma vez criado os métodos vamos desenvolvê-los, como abaixo:

{ TFrameComboGenerics } procedure TFrameComboGenerics.CreateCombo(Table_, Field_: string; ValueId_: Integer); begin Table :=Table_; Field :=Field_; ValueId:=ValueId_; end; procedure TFrameComboGenerics.edtComboKeyPress(Sender: TObject; var Key: Char); begin if Key=#13 then begin if edtCombo.Items.IndexOf(edtCombo.Text)=-1 then begin SaveCombo; // LbMensagem.Caption:=''; // LbMensagem.Caption:='Registro SALVO'; Sleep(200); // LbMensagem.Caption:='...'; // LbMensagem.Repaint; end; end; end; function TFrameComboGenerics.GetIdValue: Integer; var QValue:TUtilSqlSuid; begin //buscar o ID da string selecionada QValue:=TUtilSqlSuid.Create(Table, Field, 0); QValue.CreateOpenQuery('Select * from '+Table+' Where '+field+ ' = '''+edtCombo.Text+''''); Result:=QValue.GetIntegerField('Id'+Table); QValue.free; end; procedure TFrameComboGenerics.LoadCombo; begin [atráves de uma lista encadeada estamos carregando o combobox] QSql:=TUtilSqlSuid.Create(Table, Field, ValueId); QSql.OpenSimpleQuery; Qsql.first; QList:=TUtilList.Create; while not Qsql.Eof do begin QList.Add(QSql.GetStringField(Field)); QSql.next; end; [Colocamos a lista com todos os dados da tabel para dentro do ComboBox] edtCombo.UtilList:=QList; QSql.Free; end; procedure TFrameComboGenerics.ReposicionaLabel; begin // LbMensagem.Left:=LbTitulo.Width+5; end; procedure TFrameComboGenerics.SaveCombo; begin //Atra´ves do estanciamento da classe estamos salvando o registro inserido, claro //que seria legal criar um regra para verificar duplicidade QSql:=TUtilSqlSuid.Create(Table, Field, ValueId); QSql.OpenSimpleQuery; QSql.ClearList; QSql.AddStringField(Field,''+UpperCase(edtCombo.Text)+''); QSql.ExecuteInsert ; QSql.Free; end; procedure TFrameComboGenerics.SetTitulo(msgTitulo: string); begin //Alterar o caption do Label LbTitulo.Caption:=msgTitulo; LbTitulo.Repaint; end; procedure TFrameComboGenerics.SetValue( IdValue: Integer); var QValue:TUtilSqlSuid; begin //Busca através do ID o valor String Correspondente QValue:=TUtilSqlSuid.Create(Table, 'Id'+Table, IdValue); QValue.OpenQuery; edtCombo.ItemIndex:=edtCombo.Items.IndexOf(QValue.GetStringField(Field)); QValue.free; end; end.
Listagem 4. Desenvolvimento dos métodos do frame criado

Feito isso é só inserir no formulário e setar os métodos necessários assim:

FrameComboLocal.CreateCombo('reg_LocalChale','Nome',0); //Estou aqui informando o nome da tabela e qual campo desejo que popule o combobox FrameComboLocal.LoadCombo; //Realizando o LoadCombo para carregar os dados FrameComboLocal.SetValue(QSql.GetIntegerField('IdLocal')); //Seto um registro default com o ID que puxo do banco
Listagem 5. Utilizando o frame
Figura 4. Resultado final

Com isso podemos inserir este frame em vários forms, trocando os parâmetros do create.

Artigos relacionados