Limpando Objeto Dinâmico.

Delphi

09/04/2013

Boa tarde!

Estou com uma dúvida, não sei se e atoa ou e complicado mesmo. Estou tentando trabalhar com MVC no Delphi em OOP, até aqui estou levando tranquilo, está funcionando os cruds e herança na parte da aplicação, mas vamos a minha dúvida.

Ex: Estou tentando limpar um campo que seja passado por referência. Por exemplo.

Uma procedure para limpar.
Procedure LimparCampos(Objetos: TComponent);

Dai quando clico no botão qualquer chamando a procedure LimparCampos(TEdit) ele limparia todos os TEdits.

For I := 0 To Self.ComponentCount - 1 Do
Begin
   If (TComponent(Objetos).Components[I] Is TEdit) Then
      (TComponent(Objetos).Components[I] As TEdit).Clear;
End;


Alguém entendeu mais ou menos o que estou tentando fazer? Passando um TComponent por exemplo TEdit ou TMaskEdit ou qualquer outro, limpando somente o que estou passando. Obrigado!
Jean Teixeira

Jean Teixeira

Curtidas 0

Respostas

Jean Teixeira

Jean Teixeira

09/04/2013

Do jeito que estou tetando fazer não está dando certo, alguém pode me da uma luz? rsrs! Obrigado.
GOSTEI 0
Douglas

Douglas

09/04/2013

Boa noite Lucio,

implemente o código abaixo:

procedure TForm1.LimpaObjeto;
var
  i : Integer;
begin
  for i := 0 to ComponentCount - 1 do
  begin
    if Components[i] is TEdit then // Verifica se o componente é do tipo TEdit, antes de limpar o objeto passado no i.
    begin
     // Aqui fiz um TypeCast de TEdit pegando a propriedade clear. Nada impediria de fazer com "AS" funciona
     // da mesma forma exemplo: (Components[i] as TEdit).Clear;
      TEdit(Components[i]).Clear;
    end;

    if Components[i] is TMaskEdit then // O mesmo ocorre aqui.
    begin
     TMaskEdit(Components[i]).Clear;
    end;

  end;
end;


Espero que tenha ficado claro e até mais.

Qualquer dúvida é só postar.
GOSTEI 0
Marco Salles

Marco Salles

09/04/2013

tente

uses
rtti;

procedure Limpar(AOwner:TWinControl;T:TClass);
var
  C:TComponent;
  ctx:TRttiContext;
  tfield:TRttiType;
  metodo:TRttiMethod;
  aParams  : Array of TValue;
begin

tfield:=ctx.GetType(T);
metodo:=tfield.GetMethod('Clear');
if metodo = nil then
 exit;
for C in AOwner do
  if C is T then
    metodo.Invoke(C,aParams);
end;

GOSTEI 0
Jean Teixeira

Jean Teixeira

09/04/2013

tente

uses
rtti;

procedure Limpar(AOwner:TWinControl;T:TClass);
var
  C:TComponent;
  ctx:TRttiContext;
  tfield:TRttiType;
  metodo:TRttiMethod;
  aParams  : Array of TValue;
begin

tfield:=ctx.GetType(T);
metodo:=tfield.GetMethod('Clear');
if metodo = nil then
 exit;
for C in AOwner do
  if C is T then
    metodo.Invoke(C,aParams);
end;



Bom dia! Esse vai funcionar do Delphi 2010 se eu não me engano para frete. Estou a utilizar o 2007. Mas a ideia e a mesma, quero passar um component e a função fazer somente ele, mas dentro da função vai ter TEdit, TMaskEdit e entre outros.
GOSTEI 0
Jean Teixeira

Jean Teixeira

09/04/2013

Boa noite Lucio,

implemente o código abaixo:

procedure TForm1.LimpaObjeto;
var
  i : Integer;
begin
  for i := 0 to ComponentCount - 1 do
  begin
    if Components[i] is TEdit then // Verifica se o componente é do tipo TEdit, antes de limpar o objeto passado no i.
    begin
     // Aqui fiz um TypeCast de TEdit pegando a propriedade clear. Nada impediria de fazer com "AS" funciona
     // da mesma forma exemplo: (Components[i] as TEdit).Clear;
      TEdit(Components[i]).Clear;
    end;

    if Components[i] is TMaskEdit then // O mesmo ocorre aqui.
    begin
     TMaskEdit(Components[i]).Clear;
    end;

  end;
end;


Espero que tenha ficado claro e até mais.

Qualquer dúvida é só postar.


Bom dia! Essa e a ideia, quero passar um component e a função fazer somente ele, mas dentro da função vai ter TEdit, TMaskEdit e entre outros. Fazer um Generic praticamente para limpar campos, mas um especifico. Por exemplo:

Imagina um cadastro onde tem Combo, Edit, Mask, Lookup e entre outros, mas quando for um cadastro novo eu chamo por exemplo. LimpaCampos(TEdit). A função vai limpar somente os Edit e os outros ficam do mesmo jeito. Acho que ficou mais claro agora, já tentei de varias formas, quero uma coisa padronizada, porque eu dei conta de fazer funcionar mas passando um inteiro e fazendo um case dentro da função, mas assim não fica tão legal. Mas obrigado mesmo assim!
GOSTEI 0
Marco Salles

Marco Salles

09/04/2013

Olá então ha uns tenpos atrás eu fiz algo parecido em

http://marcosalles.wordpress.com/2010/05/15/limpar-campos-formulario-panel-controle-delph/

e adaptei para o seu caso



uses
TypInfo,StrUtils,wideStrings;

procedure Limpar(Controle: TWincontrol; T:TClass;const PropName:String );

 //procedure interna ao metodo
procedure SetPropStr(Instance: TObject; const PropName:string;
                               const Value: Variant);
 var
   P:Pointer;
   E:String;
 begin
   E:=VarToWideStr(GetPropValue(Instance,PropName));
   p:=Pointer(strtoint(E));
   TStringList(TObject(P)).Text:=Value;
 end;
 //fim de procedure Interna
 const
   Propriedade:Array[0..4] of String =
                          ('Text','ItemIndex','Checked','Lines','Items');
var
 index,i:Integer;
begin
try
for index:=0 to Controle.ControlCount -1 do
   if Controle.Controls[index] is T then
case AnsiIndexStr(PropName,Propriedade) of
0:SetPropValue(Controle.Controls[index],Propriedade[0],'');
1:SetPropValue(Controle.Controls[index],Propriedade[1],-1);
2:SetPropValue(Controle.Controls[index],Propriedade[2],false);
3:SetPropStr(Controle.Controls[index],Propriedade[3],'');
4:SetPropStr(Controle.Controls[index],Propriedade[4],'');
end;
except
 Showmessage('Propriedade "'+PropName+'" Não existe para a Class '+T.ClassName);
end;
end;


Exemplos de uso

Limpar(Self,TEdit,'Text');
Limpar(self,TMaskedit,'Text');
Limpar(self,TCheckBox,'Checked');
limpar(self,TListBox,'Items');
Limpar(self,TMemo,'Lines');


[]sds e boa sorte
GOSTEI 0
Jean Teixeira

Jean Teixeira

09/04/2013

Olá então ha uns tenpos atrás eu fiz algo parecido em

http://marcosalles.wordpress.com/2010/05/15/limpar-campos-formulario-panel-controle-delph/

e adaptei para o seu caso



uses
TypInfo,StrUtils,wideStrings;

procedure Limpar(Controle: TWincontrol; T:TClass;const PropName:String );

 //procedure interna ao metodo
procedure SetPropStr(Instance: TObject; const PropName:string;
                               const Value: Variant);
 var
   P:Pointer;
   E:String;
 begin
   E:=VarToWideStr(GetPropValue(Instance,PropName));
   p:=Pointer(strtoint(E));
   TStringList(TObject(P)).Text:=Value;
 end;
 //fim de procedure Interna
 const
   Propriedade:Array[0..4] of String =
                          ('Text','ItemIndex','Checked','Lines','Items');
var
 index,i:Integer;
begin
try
for index:=0 to Controle.ControlCount -1 do
   if Controle.Controls[index] is T then
case AnsiIndexStr(PropName,Propriedade) of
0:SetPropValue(Controle.Controls[index],Propriedade[0],'');
1:SetPropValue(Controle.Controls[index],Propriedade[1],-1);
2:SetPropValue(Controle.Controls[index],Propriedade[2],false);
3:SetPropStr(Controle.Controls[index],Propriedade[3],'');
4:SetPropStr(Controle.Controls[index],Propriedade[4],'');
end;
except
 Showmessage('Propriedade "'+PropName+'" Não existe para a Class '+T.ClassName);
end;
end;


Exemplos de uso

Limpar(Self,TEdit,'Text');
Limpar(self,TMaskedit,'Text');
Limpar(self,TCheckBox,'Checked');
limpar(self,TListBox,'Items');
Limpar(self,TMemo,'Lines');


[]sds e boa sorte


Valeu, vou testar! Obrigado...
GOSTEI 0
Douglas

Douglas

09/04/2013

Entendi. Realmente a solução do Marco,
esta nos padrões que você quer Lucio.
GOSTEI 0
Jean Teixeira

Jean Teixeira

09/04/2013

Entendi. Realmente a solução do Marco,
esta nos padrões que você quer Lucio.


To tentando fazer o mais padrão e organizado possível. Obrigado a todos. Com certeza voltarei para mais dúvidas. Vlw.
GOSTEI 0
Marco Salles

Marco Salles

09/04/2013

Deixo um adendo que a rotina aplica no Parent (Control) e não nos Owner (Components) .

Assim se vc tiver dois edits , um dentro de um panel (que esta dentro de um Form) e outro Edit dentro do mesmo Form

Limpar(Self,TEdit,'Text'); ->> Limpara o Edit relativo (Parent) do Form

Limpar(SEUPANEL,TEdit,'Text'); -->> Limpara o Edit relatiovo ao SeuPAnel


Para alterar esta caracteristica modifique a varredura na rotina de Control para Components

[]sds
GOSTEI 0
Jean Teixeira

Jean Teixeira

09/04/2013

Deixo um adendo que a rotina aplica no Parent (Control) e não nos Owner (Components) .

Assim se vc tiver dois edits , um dentro de um panel (que esta dentro de um Form) e outro Edit dentro do mesmo Form

Limpar(Self,TEdit,'Text'); ->> Limpara o Edit relativo (Parent) do Form

Limpar(SEUPANEL,TEdit,'Text'); -->> Limpara o Edit relatiovo ao SeuPAnel


Para alterar esta caracteristica modifique a varredura na rotina de Control para Components

[]sds


Valeu, abraços!
GOSTEI 0
POSTAR