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:
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:
- File > New > Frame (Insira um novo Frame, altere a propriedade NAME para FrameEndereco e salve);
- Após insira edit's e label's deixando ele como na figura abaixo;
- 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.
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';
ou, se preferir,
with FrameEndereco1 do begin
edtRua.Text:='Rua Caipos';
edtNumero.Text:='111'
end;
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:
- File > New > Frame(Insira um novo Frame, altere a propriedade NAME para FrameComboGenerics e salve);
- Após, insira UtilComboBox(Ler artigo) e label's deixando ele como na figura abaixo;
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;
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.
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
Com isso podemos inserir este frame em vários forms, trocando os parâmetros do create.