Limpando Objeto Dinâmico.

09/04/2013

14

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!
Responder

Posts

09/04/2013

Jean Teixeira

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

09/04/2013

Douglas

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.
Responder

09/04/2013

Marco Salles

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;

Responder

10/04/2013

Jean Teixeira

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.
Responder

10/04/2013

Jean Teixeira

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!
Responder

10/04/2013

Marco Salles

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
Responder

10/04/2013

Jean Teixeira

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...
Responder

10/04/2013

Douglas

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

10/04/2013

Jean Teixeira

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.
Responder

11/04/2013

Marco Salles

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
Responder

11/04/2013

Jean Teixeira

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!
Responder