Form e Factory method ?
20/03/2006
0
Estou usando a técnica de Factory method para criar os forms usando o nome do form, mais estou com um problema.
Tenho um cadastro de produtos criado, depois crio apartir dele uma tela de consulta grupo, só que, quando tento fazer um TypeCast do Consulta grupo para o Cadastro de produtos, dar um erro de memoria, como se o cadastro de produtos não tivesse criado.
Alguém pode me dar uma ajudinha ?
Obrigada.
Renatacoimbra
Posts
20/03/2006
Marco Salles
Se voce quiser dar uma olhada pode procura por Factory method , que vai achar
20/03/2006
Renatacoimbra
eu tenho o exemplo, da revista de Nro 69, estou usando ele, o problema é esse q citei no post acima.
usando esse método, quando tento fazer um typeCast tipo:
CadProdutos.Edit1.Text := CadGrupo.DataSetCAMPO.asString;
dar erro, como se o cadastro de produtos não tivesse criado.
[]´s
21/03/2006
Marco Salles
Como voce cria o Cadastro Tela de Consulta a partir do Form Cadastro de produtos ????
Voce continua usando o método ??? Ou cria usando application.crteateForm????
21/03/2006
Michael
Essa é uma das desvantagens de se usar uma fábrica - pelo menos como a concepção padrão define o termo: cada artefato produzido por ela é independente um do outro, sequer sabem que eles existem. Isso poderia ser contornado se todos os objetos criados pela factory fossem do mesmo tipo, o que não é o caso de formulários Delphi.
[]´s
21/03/2006
Renatacoimbra
Eu estou criando meu Cadastro de Produtos apartir do Projeto usando Factory, daí do cadastro de produtos estou criando um outro form que é uma consulta.
Tentei criar o form COnsulta das duas formas usando o método Factory ou usando o método tradicinal, das duas formas dar o erro.
Olha a classe:
TCriaForm = class private FList: TStrings; public constructor Create; destructor Destroy; override; function Nome(const aFormName: string): TFrm_Form; procedure RegisterForm(const aFormName: string; aFormClass: TComponentClass); end; var _CriaForm: TCriaForm; function CriaForm: TCriaForm; implementation constructor TCriaForm.Create; begin inherited Create; FList := TStringList.Create; end; function TCriaForm.Nome(const aFormName: string): TFrm_Form; var i : integer ; begin //result := nil; i := FList.IndexOf(aFormName); Assert(i <> -1, ´Formulário ´+ aFormName +´ não existe´); Result := TComponentClass(FList.Objects[i]).Create(nil) as TFrm_Form; end; destructor TCriaForm.Destroy; begin FList.Free; inherited; end; procedure TCriaForm.RegisterForm(const aFormName: string; aFormClass: TComponentClass); var i: integer; begin i := FList.IndexOf(aFormName); if i = -1 then FList.AddObject(aFormName, TObject(aFormClass)); end; function CriaForm: TCriaForm; begin result := _CriaForm; end; initialization _CriaForm := TCriaForm.Create; finalization _CriaForm.Free; end.
Frm_ConsultaGrupo := Frm_ConsultaGrupo.Create(nil); Frm_ConsultaGrupo.ShowModal;
21/03/2006
Marco Salles
1) No[b:af80637888] form Principal declare FForm como Public [/b:af80637888]ou a deixe em private e crie um método para acessa-lo .. Mas vamos deiza-la em Public para não nos estender
2)No form Produtos na parte [b:af80637888]Implementation[/b:af80637888] declare
na seccçao [b:af80637888]Public[/b:af80637888] Um Variavel
public FFormB : TForm; { Public declarations }
implementation uses FormFactoryU;
3)No form Frm_ConsultaGrupo na secção implementation declare
implementation uses FormFactoryU,unitDoFormProduto,UnitDoFormPrincipal;
Não esqueça de fazer Tambem na unit do Form Consulta
initialization FormFactory.RegisterForm(´FormConsulat´, TFormConsulta);
Para criar o FormConsulta atraves do FormProduto
FFormB := FormFactory.CreateForm(´FormConsulta´); FFormB.ShowModal; FreeAndNil(FFormB);
Agora com essas definiçoes , voce pode acessar as propriedades , fazendo o TypCast Correto
Por exemplo
TformProduto(FormPrincipal.FForm).Componente.Propriedade:= TformConsulta(TformProduto(FormPrincipal.FForm).FFormB).Componete.Propriedade;
So que isto conforme foi mencionado , descaracteriza o factory Method
O Grande problema é que apos voce criar um form usando o Método , por exemplo o formProduto , se no formulario , voce incluir um Botão e testar
If assigned(FormProduto) Then
[b:af80637888]Voce vera que é Nil.. Por isso as mensagens de acesso Violado que voce deve estar recebendo[/b:af80637888]
21/03/2006
Massuda
O que você pode fazer é atribuir o valor retornado pelo factory à variável frm_produtos ou fazer a classe do form identificado por ´Frm_Produtos´ ser um singleton (se seu sistema permitir ter apenas um form desse tipo).
21/03/2006
Marco Salles
[b:342af0d8d1]isto que eu quis dizer , quando deu o exemplo do Assigned[/b:342af0d8d1]
é uma maneira mais limpa de fazer a conversão.. Pois afinal voce estara se referindo ao mesmo form apenas com outro Nome
:arrow: Na criação :do [b:342af0d8d1]form produto[/b:342af0d8d1].. Pode ser no[b:342af0d8d1] OnShow[/b:342af0d8d1]
TForm(formProduto):=(FormPrincipal.FForm);
[b:342af0d8d1]a unica diferença ai é que voce nesse caso tem que incluir na secçao uses do FormProduto a Unit Do Form Principal... [/b:342af0d8d1]O Que não era necessário na conversão anterior que lhe passei..
:arrow: Na criação do [b:342af0d8d1]FormCadastro [/b:342af0d8d1], pode ser no[b:342af0d8d1] OnShow[/b:342af0d8d1]
Tform(FormCadastro):=FormProduto.FFormB;
Ai basta fazer em qualquer botão ou método
exemplo :
FormProduto.Edit1.text:=FormCadastro.Edit1.text;
[b:342af0d8d1]Obs) Renata estas atribuiçoes tem que vir no OnShow antes de qualquer método , senão pode aparecer erros de acesso Violado[/b:342af0d8d1]
Isto eu nun entendi :?: :?: :?:
Mas pode testar isto renata que dá
21/03/2006
Massuda
21/03/2006
Renatacoimbra
Nos testes que fiz funcionou blz.
Mais eu resolvir a não usar esse método para criação dos Forms, eu uso módulos em Packages BPL, vai dar muitos problemas pra mim pelo jeito.
Obrigada.
Clique aqui para fazer login e interagir na Comunidade :)