Find a component by name

Asked

Viewed 2,481 times

1

I have a string:

var
  vMinhastring : string;
begin
  vMinhastring := 'Edit1';

In my form I have a Tedit Compomente with the name Edit1. How I pass some value to my Edit1, using vMinhastring as the Component name?

  vMinhastring.text := 'batatinha';

I’m trying to do this, but I’m having problems:

contElem := 1;
Rdb1:= TRadioGroup.Create(TabSheet1);
Rdb1.Parent:= TabSheet1;
Rdb1.OnExit := Validacao;
Rdb1.Name:='Rdb'+IntToStr(contElem);
Rdb1.Items.Add('C');

Edit := TMaskEdit.Create(TabSheet1);
Edit.Parent:= TabSheet1;
Edit.Name:='Edit'+IntToStr(contElem);
Edit.Clear;
Edit.EditMask := ('!99;1;');

contElem := 2;
Rdb1:= TRadioGroup.Create(TabSheet1);
Rdb1.Parent:= TabSheet1;
Rdb1.OnExit := Validacao;
Rdb1.Name:='Rdb'+IntToStr(contElem);
Rdb1.Items.Add('C');

Edit := TMaskEdit.Create(TabSheet1);
Edit.Parent:= TabSheet1;
Edit.Name:='Edit'+IntToStr(contElem);
Edit.Clear;
Edit.EditMask := ('!99;1;');

I created a trial:

procedure TFCad_AnaliseDeTendencias.Validacao(Sender: TObject);
var
 name, name2 :string;
 i : integer;
begin
   name := TRadioGroup(Sender).Name;
   name2 := '';
   for i := 1 to Length(name) do
   begin
      if name[i] in ['0'..'9'] then
         name2 := name2 + name[i];
   end;
   name2 := 'Edit'+name2;
   TMaskEdit(FindComponent(name2)).Text := '01'; //Esta dando erro aqui.
end;

Is making a mistake of

Access Violation at address

  • What you need is not Edit1.Text = vMinhastring; ?

  • that’s not what I need.

  • You will also need to specify the type of the component. Ex: 'Edit1' of type 'Tedit'. Having this in m]aos you will work with Typecast and/or RTTI. If you need an example just ask, but if you do a search on Typecast and rtti you will understand what I am saying.

  • So it seems to me that you want to find a control dynamically in the form having only his name, that’s it?

  • That’s right @Pagotti

  • @Victortadashi has some example, using Typecast?

  • @Tiagocasanova took his last edition and no error occurs, a revised!

  • Was any of the answer helpful? Don’t forget to choose one and mark it so it can be used if someone has a similar question!

Show 3 more comments

3 answers

1


Well, I built a prototype with RTTI that looks better. Follow the code:

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ExtCtrls, Vcl.StdCtrls;

type
  TForm1 = class(TForm)
    Edit1: TEdit;
    Edit2: TEdit;
    Button1: TButton;
    Panel1: TPanel;
    procedure Button1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    function CriarComponente(AClassType: TClass; AName: String; AParent: TWinControl): TComponent;
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

uses
  Rtti;

{$R *.dfm}

{ TForm1 }



procedure TForm1.Button1Click(Sender: TObject);
begin

  CriarComponente(GetClass(Edit1.Text), Edit2.Text, Panel1);

end;



function TForm1.CriarComponente(AClassType: TClass; AName: String; AParent: TWinControl): TComponent;
var
  RttiContext: TRttiContext;
  RttiInstanceType: TRttiInstanceType;
  Value: TValue;
begin

  RttiInstanceType                       := (RttiContext.GetType(AClassType) as TRttiInstanceType);
  Value                                  := RttiInstanceType.GetMethod('Create').Invoke(RttiInstanceType.metaClassType, [self]);
  (Value.AsObject as TWinControl).Parent := AParent;

end;



procedure TForm1.FormCreate(Sender: TObject);
begin
  RegisterClasses([TButton, TForm, TEdit]);
end;

end.

On the program screen, I added 2 edits where you will inform the component type and its name, a button to run, and a panel to be the components Parent.

Obs.: It is necessary to check the classes you can create, ex: RegisterClasses([TButton, TForm, TEdit]);

  • In reality what he asked is not how to create a new component but how to add a text to an existing one just knowing the name

  • @Sorack, you are right

0

Look at this:

procedure TForm13.Button1Click(Sender: TObject);
Var
   tabSheet: TTabSheet;
   AComponent: TComponent;
   aIndex: Integer;
begin
   aIndex:=-1;

   AComponent := FindComponent('TabSheet1');
   if Assigned(AComponent) then
     if AComponent is TTabSheet then
       aIndex := TTabSheet(AComponent).PageIndex; //get the index of the 'TabSheet1'  

   tabSheet := TTabSheet.Create(PageControl1);
   tabSheet.PageControl := PageControl1;
   tabSheet.Caption := 'My TabSheet'+IntToStr(PageControl1.PageCount);
   if aIndex>-1 then
     tabSheet.PageIndex := aIndex; //Set the index of the new TabSheet
end;

0

You can use the function System.Classes.TComponent.FindComponent:

TEdit(FindComponent(vMinhastring)).Text := 'Meu texto';

Findcomponent

Original: Findcomponent Returns the Component in the Components Property array with the name that Matches the string in the Aname Parameter.

Free translation: Findcomponent returns the component in the Component array property with the name that matches the string in the Aname parameter.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.