Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Varios (https://www.clubdelphi.com/foros/forumdisplay.php?f=11)
-   -   Buscar componentes de un formulario usando rtti (https://www.clubdelphi.com/foros/showthread.php?t=96165)

juank1971 22-03-2023 20:18:36

Buscar componentes de un formulario usando rtti
 
saludos como puedo buscar todos por ejemplo los TstringGrids de un formulario usando rtti ?

algo por ejemplo como esto
Código Delphi [-]
for i := 0 to Formulario.ComponentCount - 1 do
   begin
     if Formulario.Components[i].ClassName= 'TStringGrid' then
    begin
      Grid := TStringGrid(Formulario.Components[i]); // encontró  alguno
      if Grid.ColumnCount > 0 then // comprueba que tenga columnas
        try
......................................
quisiera hacer esto con rtti, he tratado de buscar en google y clubdelphi pero todos los ejemplos buscan propiedades y demas de las clases no instanciadas.

o por ejemplo esto otro quisiera tambien hacerlo con RTTI:

Código Delphi [-]
function GetLinkGridToDataSource(Formulario: TForm; Grid: string): TLinkGridToDataSource;
var
   l:TLinkGridToDataSource; s:TStringGrid;
begin
  result := nil;
  for var i := 0 to Formulario.ComponentCount - 1 do
    if Formulario.Components[i] is TLinkGridToDataSource then
     begin
      l:= Formulario.Components[i] as TLinkGridToDataSource;
      if l.GridControl is TStringGrid then
       begin
       s:= l.GridControl as TStringGrid;
       if Grid = s.name then
        result := l;
       end;
     end;
end;

Neftali [Germán.Estévez] 23-03-2023 09:27:33

Cita:

Empezado por juank1971 (Mensaje 550808)
como puedo buscar todos por ejemplo los TstringGrids de un formulario usando rtti ?

La forma de hacerlo es utilizando FindComponent de forma similar a como se ve en el código; Mejor usando IS que la comparación por ClassName.
Este recorrido es lento. Si necesitas hacerlo mçás de una vez, puedes almacenar los componentes en una Lista (TObjectList) para no tenerlo que hacer más de una vez.

Otra opción es crear manualmente esa lista al crear el formulario.

Código Delphi [-]
  Memo1.Lines.Clear;
  for var i:integer := 0 to ComponentCount - 1 do
    if Components[i] is TStringGrid then
      Memo1.Lines.Add(Components[i].Name + ' -> ClassName:' + Components[i].ClassName);

Este código funciona tanto para VCL como para FMX.
Para buscar otros componentes como el que comentas (clase TLinkGridToDataSource) basta adaptar ese código para la nueva clase.

Código Delphi [-]
  for var i:integer := 0 to ComponentCount - 1 do
    if Components[i] is TLinkGridToDataSource then
      Memo1.Lines.Add(Components[i].Name + ' -> ClassName:' + Components[i].ClassName);

En cuanto a esta cabecera:

Código Delphi [-]
function GetLinkGridToDataSource(Formulario: TForm; Grid: string): TLinkGridToDataSource;

En estos casos es mejor pasar directamente los componentes, no los nombres (parea no tener que realizar las búsquedas).

Código Delphi [-]
function GetLinkGridToDataSource(Formulario:TForm; Grid: TStringGrid): TLinkGridToDataSource;

Con una implementación similar a esta:

Código Delphi [-]
function GetLinkGridToDataSource(Formulario:TForm; Grid: TStringGrid): TLinkGridToDataSource;
begin
  Result := nil;
  for var i:integer := 0 to Formulario.ComponentCount - 1 do
    if Formulario.Components[i] is TLinkGridToDataSource then begin
      var comp:TComponent := Formulario.Components[i];
      if Assigned(TLinkGridToDataSource(comp).GridControl) then
        if (TLinkGridToDataSource(comp).GridControl = Grid) then begin
          Result := TLinkGridToDataSource(comp);
          Exit;
        end;
    end;
end;

Neftali [Germán.Estévez] 23-03-2023 09:43:53

Si aplicamos el último procedimiento al primero que hemos usado para buscar los TStringGrids, podríamos hacer algo como eso:

Código Delphi [-]
procedure TForm4.Button1Click(Sender: TObject);
begin
  Memo1.Lines.Clear;
  for var i:integer := 0 to ComponentCount - 1 do
    if Components[i] is TStringGrid then begin
      var lds: TLinkGridToDataSource := GetLinkGridToDataSource(Self, TStringGrid(Components[i]));
      if Assigned(lds) then
        Memo1.Lines.Add('Grid: ' + Components[i].Name + ' tiene asignado LinkDS: ' + lds.Name)
      else
        Memo1.Lines.Add('Grid: ' + Components[i].Name + ' no tiene asignado LinkDS');
    end;
end;

juank1971 23-03-2023 13:16:24

que bien gracias , no hay necesidad de usar rtti entonces.
rtti a mi modo de ver al parecer es mas bien cuando quiero cambiar propiedades e run time
como por ejemplo esta función para habilitar los componentes de un Tlayout al editar,
ahora estoy recordando ver una función para algo de esto en tu blog neftali.
Código Delphi [-]
procedure HabilitarComponentes(LY: TLayout; Hab: boolean);
begin
  with LY do
    for var i := 0 to ControlsCount - 1 do
    begin
      if Controls[i] is TEdit then
        (Controls[i] as TEdit).CanFocus := Hab;
       
      if Controls[i] is TMemo then
       (Controls[i] as TMemo).CanFocus := Hab;
      
     if Controls[i] is TDateEdit then
       (Controls[i] as TDateEdit).CanFocus := Hab;
     
     if Controls[i] is TcomboBox then
        (Controls[i] as TcomboBox).Enabled := Hab;
    end;
end;

Neftali [Germán.Estévez] 23-03-2023 15:06:52

Cita:

Empezado por juank1971 (Mensaje 550815)
como por ejemplo esta función para habilitar los componentes de un Tlayout al editar,
ahora estoy recordando ver una función para algo de esto en tu blog neftali.
Código Delphi [-]procedure HabilitarComponentes(LY: TLayout; Hab: boolean); begin with LY do for var i := 0 to ControlsCount - 1 do begin if Controls[i] is TEdit then (Controls[i] as TEdit).CanFocus := Hab; if Controls[i] is TMemo then (Controls[i] as TMemo).CanFocus := Hab; if Controls[i] is TDateEdit then (Controls[i] as TDateEdit).CanFocus := Hab; if Controls[i] is TcomboBox then (Controls[i] as TcomboBox).Enabled := Hab; end; end;

Es posible.
Justo para evitar código como el que muestras ahí, es para lo que va muy bien usar RTTI.


La franja horaria es GMT +2. Ahora son las 10:12:22.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi