Delphi + Firemonkey: dynamic component design created at runtime

Asked

Viewed 1,590 times

2

I have a TForm which allows the system user to create components at runtime (TButton, TRadioButton, TLabel, TPanel, among others).

This functionality is working, but now the need has arisen for the user to create these components taking into account another component previously selected on TForm, that is, it can create a TPanel, select it, and without then create a button within this TPanel.

Until now I used the property Parent of Form main and set that in time design using the same, but dynamically I am not able to do. I have tried using the Focused.GetObject that picks up the selected object, but obviously it always picks up the TButton that I clicked to create the component and not the component that was in previous focus.

I tried using the FindComponent by the name of the previous component but also could not.

Application Screen:

inserir a descrição da imagem aqui

2 answers

2


There are a few ways to deal with this issue. I’ll explain how I did the last time I needed something similar.

First you will need a variable that will hold the value of the last, let’s call, container clicked, which in your case it seems may be a Tpanel. When the person adds a Component to the form, you will see which last Tpanel was clicked, and use it to set the property Parent of the added Component.

That would be the logic. I also recommend, in order to facilitate the user’s understanding, you paint the edges of the last clicked Tpanel, blue for example, so that the user knows which one is selected. If I am not mistaken in the Firemonkey the Tpanel does not have borders, but the Trectangle possessed. If you add one inside the Tpanel with the Align property set to Client inside it, you can paint the edges.

Let’s make a practical example:

type
  TfrmExemplo = class(TForm)
    Panel1: TPanel;
    Button1: TButton;
    procedure Panel1Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    ObjetoSelecionado: TFmxObject;
  end;

Note that in the form I have declared in public a variable Objectified which, as I said, will be responsible for storing the last panel selected by the user. Let’s see now the contents of procedure Panel1Click:

procedure TfrmExemplo.Panel1Click(Sender: TObject);
begin
  ObjetoSelecionado := TFmxObject(Panel1);
end;

After that we have the last panel clicked by the user, and as I said in that same procedure you could paint the edges to be clearer. Now let’s look at the content of procedure Button1Click:

procedure TfrmExemplo.Button1Click(Sender: TObject);
var
  btnAux: TButton;
begin
  btnAux := TButton.Create(ObjetoSelecionado);
  btnAux.Parent := ObjetoSelecionado;
end;

When performing this action, you will create a button inside the previously selected panel, thus solving your question.

  • About painting the edges, yes, you’re right, in my case, I put a tselector on it and it takes the properties of the same, can resize in the way I want, this is already ok. About creating the variable to store, yes, you’re also right, I’ve even done this, however, my doubt is this same, how to use the name of the component previously clicked and turns it into Fmobject so I can use it as the other’s Parent?

  • I put an image in the original question, above, a small part of my software, exemplifying like this now. I already add the components, take the properties, etc. I just really need to insert one component into the other that is already selected.

  • I modified the answer by giving a more practical example of the proposed logic. Please take a look and see if it suits you.

  • Cool, first of all I appreciate the formatting and improvements in the question and answer, I will pass to the project your tips and return to punctuate your answer. Thank you.

  • Precise and perfect answer, I thought of many things but the answer was very simple. I thank you for the time you gave to help;

  • Wonderful, I’m glad I helped you. Good luck!

Show 1 more comment

0

Only for those with the same problem, the solution is simple, as Pedro explained above also works, but for me, the following example worked more adequately to my need.

ComponenteCriadoRuntime.Parent := TFmxObject(FindComponent(edtName.Text));

Where ComponenteCriadoRuntime is the type TControl and instill in him any class I desire. edtName is a component of the TEditcontaining the property Name of the element that is selected in my form using Pedro’s answer above.

That’s how it works perfectly.

Browser other questions tagged

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