Как установить динамическую панель в качестве родителя компонента?

ну, я создаю во время выполнения 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
это мне очень помогло, и спасибо за подробное объяснение использования with, чтобы не тратить слишком много времени на отладку. - person Hiram; 15.05.2019