Как да задам динамичен панел като родител на компонента?

добре, създавам по време на изпълнение TImage и Tlabel, искам тези два да бъдат дете на Tpanel, който също създавам по време на изпълнение. ето малко код:

with TPanel.Create(FlowPanelPlantillas) do
begin
  Name := 'Panel'+Query.FieldByName('ID').AsString;
  //Etc Etc
end;

и изображението

with TImage.Create(TWinControl(FindComponent('Panel'+Query.FieldByName('ID').AsString))) do
  begin
    Name:= 'P'+Query.FieldByName('ID').AsString;
    Parent := TWinControl(FindComponent('Panel'+Query.FieldByName('ID').AsString));        
  end;

това е, което правя, но не работя, панелът е създаден и се разглежда правилно, но изображението не се появява в панела, той е празен.

Използвам Delphi Rio VCL

Оценявам всяка помощ.


person Hiram    schedule 14.05.2019    source източник
comment
Използвайте променлива, когато създавате панела и задайте родителското изображение на тази променлива   -  person AnselmoMS    schedule 14.05.2019
comment
Избягвайте да използвате with. Има потенциал да ви създаде сериозни главоболия в бъдеще поради включения имплицитен обхват.   -  person Graymatter    schedule 15.05.2019
comment
вашият съвет подкрепя отговора на Реми, ще променя кода си, за да избегна използването на With.   -  person Hiram    schedule 15.05.2019


Отговори (1)


Изявление with не ви предоставя достъп до обекта, към който се отнася. Имате нужда от тази препратка, за да я присвоите на нещо, като свойство Parent. Първо трябва да запишете препратката към променлива.

Освен това не забравяйте да зададете свойството Visible.

Опитайте тази:

var
  Panel: TPanel;

Panel := TPanel.Create(FlowPanelPlantillas);
with Panel do
begin
  Name := 'Panel'+Query.FieldByName('ID').AsString;
  //Etc Etcl
  Visible := True;
end;

...

Panel := TWinControl(FindComponent('Panel'+Query.FieldByName('ID').AsString));
// or, just use the same variable already assigned
// previously, if it is still in scope...

with TImage.Create(Panel) do
begin
  Name:= 'P'+Query.FieldByName('ID').AsString;
  Parent := Panel;
  Visible := True;
end;

Наистина има много малка полза от FindComponent() и именувани обекти в правилно проектиран динамичен код. Системата за именуване е основно предназначена само за DFM поточно предаване.

По този въпрос, след като имате променлива с препратка към обект в нея, има много малка полза от with или:

var
  Panel: TPanel;
  Image: TImage;

Panel := TPanel.Create(FlowPanelPlantillas);
Panel.Name := 'Panel'+Query.FieldByName('ID').AsString;
//Etc Etcl
Panel.Visible := True;

...

Panel := TWinControl(FindComponent('Panel'+Query.FieldByName('ID').AsString));
// or, just use the same variable already assigned
// previously, if it is still in scope...

Image := TImage.Create(Panel);
Image.Name := 'P'+Query.FieldByName('ID').AsString;
Image.Parent := Panel;
Image.Visible := True;

Използването на променливи за задържане на препратките към обекти също помага при отстраняването на грешки, така че можете да сте сигурни, че вашите променливи действително получават стойностите, които очаквате. Не получавате тази опция, когато използвате with.

person Remy Lebeau    schedule 14.05.2019
comment
Помогна ми много и благодаря, че го обяснихте подробно относно използването на с, за да избегна прекарването на твърде много време в отстраняване на грешки. - person Hiram; 15.05.2019