Delphi + Firemonkey: dynamic parent in component created at runtime

2

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

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

So far I used the Parent property of Form main% and defined this in design time using it, but dynamically I can not do it. I have already tried using Focused.GetObject that takes the selected object, but obviously it always takes the TButton that I clicked to create the component and not the component that was in previous focus.

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

Application Screen:

    
asked by anonymous 09.06.2017 / 02:18

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 save the value of the last, let's call, container clicked, which in your case might seem to be a TPanel . When the person adds a component to the form, you will see which last TPanel was clicked, and use that to set the Parent property of the added component.

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

Let's take 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;

Notice that in the form I have declared in public a variable SelectedElement which, as I said, will be responsible for storing the last panel selected by the user. Now let's look at 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 make it clearer. Now let's look at the contents of procedure Button1Click :

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

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

    
09.06.2017 / 02:33
0

Only for anyone with the same problem, the solution is simple, as Peter 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 of type TControl and instantiate in it any class I want. edtName is a component of type TEdit that contains the Name property of the element that is selected in my form using Peter's answer above.

So it works perfectly.

    
19.08.2017 / 23:57