Creating controls on TPageControl pages at runtime

I can drop a TPagecontrol on a form, add a tabsheet, and place a TPanel on the tabsheet and i can change the color of the Tpanel.

I can't seem to do this at runtime !  Why?

   AUnit:= TPanel.Create(ATabSheet);
    AUnit.Parent:= ATabSheet;
    AUnit.ParentColor:= False;
    AUnit.BevelOuter:= bvRaised;
    AUnit.BevelInner:= bvLowered;
    AUnit.Color:= clGreen;
Looking_4_AnswersAsked:
Who is Participating?
 
Ephraim WangoyaConnect With a Mentor Commented:
For the panel to take on te color you assign it, you must set the ParentBackground to False
AUnit.ParentBackground := False;

Ialso changed how you check whether to start adding panels to the next line
if (P + W ) < ATabSheet.ClientWidth then..

procedure TfrmMain.UpdateUnits(ATabSheet: TTabSheet);
var
 AUnit: TPanel;
 X, Y, W, H, S: Integer;
 P: Integer;
begin
 X:= 10; Y:= 10; W:= 75; H:= 75; S:= 5;
 frmDataMod.qryUnits.Active:= False;
 try
  frmDataMod.qryUnits.Parameters.ParamByName('locname').Value:= ATabSheet.Caption;
  frmDataMod.qryUnits.Active:= True;
  if frmDataMod.qryUnits.RecordCount > 0 then
  begin
  while not frmDataMod.qryUnits.EOF do
   begin
    AUnit:= TPanel.Create(ATabSheet);
    AUnit.Parent:= ATabSheet;
    AUnit.ParentColor:= False;
    AUnit.BevelOuter:= bvRaised;
    AUnit.BevelInner:= bvLowered;
    AUnit.ParentBackground := False;
    AUnit.Color:= clGreen;
    AUnit.Left:= X;
    AUnit.Top:= Y;
    AUnit.Width:= W;
    AUnit.Height:= H;
    AUnit.Caption:= frmDataMod.qryUnits.fieldByName('unit_number').AsString + ' - ' + frmDataMod.qryUnits.fieldByName('unit_type').AsString;
    frmDataMod.qryUnits.Next;
    P:= X + W + S;
    if (P + W ) < ATabSheet.ClientWidth then
     X:= P //X = X + Width + space
    else
    begin
     X:= 10;
     Y:= Y + H + S; //Y = Y + Hieght + Space
    end;
   end;
  end;//if
 except
 begin
  ShowMessage('Error retrieving units to display on location pages!');
 end;
 end;//try
end;

procedure TfrmMain.UpdateLocations;
var
 Locations: TStringList;
 I: Integer;
 APage: TTabSheet;
begin
 RemoveLocations;
 Locations:= TStringList.Create;
 frmDataMod.GetLocations(Locations, False);
 for I:= 0 to Locations.Count-1 do
 begin
  APage:=  TTabSheet.Create(pgeMain);
  APage.PageControl:= pgeMain;
  APage.Parent:= pgeMain;
  APage.Caption:= Locations[I];
  UpdateUnits(APage);
 end;
 Locations.Free;
end;


procedure TfrmMain.RemoveLocations;
var
 I: Integer;
begin
 for I:= pgeMain.PageCount-1 downto 0 do
  pgeMain.Pages[I].Destroy;
end;
0
 
cyberkiwiCommented:
That works perfectly for me, what error are you getting?
Maybe it is behind some other control, or too low?
0
 
cyberkiwiCommented:
What if you added these 3 lines?

    AUnit.BringToFront;
    AUnit.Align := alClient;
    ATabSheet.PageControl.ActivePage := ATabSheet;
0
Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
Looking_4_AnswersAuthor Commented:
The Panel is not aligned alclient

The TPagecontrol is already on the form (it is not created at runtime)

I create the TTabsheets at runtime, one at a time. After each one is created, i create the panels (many of them n a row) on each of the TTabsheets.  

I am getting the panels, its just that the have taken the color of the parent (TTabsheet) and i can't change the color.

your suggestion : AUnit.BringToFront;

does not work

setting the active page would not be appropriate in the case, as i am createing a page, adding the panels, creating another page, and so on
0
 
cyberkiwiCommented:
The 3 things to test were just to make sure you can see it

    AUnit.BringToFront;   // if it is behind another panel
    AUnit.Align := alClient;   // if the panel has been created outside of visible region of ttabsheet
    ATabSheet.PageControl.ActivePage := ATabSheet;   // if you are not looking at the right sheet!

What do you get for this line?
    showmessage(inttostr(aunit.color));

It should be 32768.
There is no reason why your code shouldn't work.
0
 
Looking_4_AnswersAuthor Commented:
well, after testing, i can do it using

  ATabsheet:= TTabsheet.Create(PageControl1);
  ATabsheet.PageControl:= PageControl1;
  ATabSheet.Parent:= PageControl1;
  APanel:= TPanel.Create(ATabSheet);
  APanel.Parent:= ATabSheet;
  APanel.Color:= clGreen;


but my code below does not work


procedure TfrmMain.UpdateUnits(ATabSheet: TTabSheet);
var
 AUnit: TPanel;
 X, Y, W, H, S: Integer;
 P: Integer;
begin
 X:= 10; Y:= 10; W:= 75; H:= 75; S:= 5;
 frmDataMod.qryUnits.Active:= False;
 try
  frmDataMod.qryUnits.Parameters.ParamByName('locname').Value:= ATabSheet.Caption;
  frmDataMod.qryUnits.Active:= True;
  if frmDataMod.qryUnits.RecordCount > 0 then
  begin
   while not frmDataMod.qryUnits.EOF do
   begin
    AUnit:= TPanel.Create(ATabSheet);
    AUnit.Parent:= ATabSheet;
    AUnit.BringToFront;
    AUnit.ParentColor:= False;
    AUnit.BevelOuter:= bvRaised;
    AUnit.BevelInner:= bvLowered;
    AUnit.Color:= clGreen; //********* THIS DOES NOT WORK *******************
    AUnit.Left:= X;
    AUnit.Top:= Y;
    AUnit.Width:= W;
    AUnit.Height:= H;
    AUnit.Caption:= frmDataMod.qryUnits.fieldByName('unit_number').AsString + ' - ' + frmDataMod.qryUnits.fieldByName('unit_type').AsString;
    frmDataMod.qryUnits.Next;
    P:= X + W + S;
    if P < ATabSheet.ClientWidth then
     X:= P //X = X + Width + space
    else
    begin
     X:= 5;
     Y:= Y + H + S; //Y = Y + Hieght + Space
    end;
   end;
  end;//if
 except
 begin
  ShowMessage('Error retrieving units to display on location pages!');
 end;
 end;//try
end;



procedure TfrmMain.UpdateLocations;
var
 Locations: TStringList;
 I: Integer;
 APage: TTabSheet;
begin
 RemoveLocations;
 Locations:= TStringList.Create;
 frmDataMod.GetLocations(Locations, False);
 for I:= 0 to Locations.Count-1 do
 begin
  APage:=  TTabSheet.Create(pgeMain);
  APage.PageControl:= pgeMain;
  APage.Parent:= pgeMain;
  APage.Caption:= Locations[I];
  UpdateUnits(APage);
 end;
 Locations.Free;
end;


procedure TfrmMain.RemoveLocations;
var
 I: Integer;
begin
 for I:= pgeMain.PageCount-1 downto 0 do
  pgeMain.Pages[I].Destroy;
end;
0
 
cyberkiwiCommented:
No idea what the issue is, but try adding the ShowMessage in my previous comment to your code, it should work.
Now, this is my test with minor variations (not controls related) to your code.

It worked.

Form has nothing but 1 PageControl, dfm listed below.
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  ComCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    pgeMain: TPageControl;
    procedure FormDblClick(Sender: TObject);
  private
    procedure UpdateLocations;
    procedure UpdateUnits(ATabSheet: TTabSheet);
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

procedure Tform1.UpdateUnits(ATabSheet: TTabSheet);
var
 AUnit: TPanel;
 X, Y, W, H, S: Integer;
 P: Integer;
 i: integer;
begin
 X:= 10; Y:= 10; W:= 75; H:= 75; S:= 5;
 try
   for i := 1 to 5 do
   begin
    AUnit:= TPanel.Create(ATabSheet);
    AUnit.Parent:= ATabSheet;
    AUnit.BringToFront;
    AUnit.ParentColor:= False;
    AUnit.BevelOuter:= bvRaised;
    AUnit.BevelInner:= bvLowered;
    AUnit.Color:= clGreen; //********* THIS DOES NOT WORK *******************
    AUnit.Left:= X;
    AUnit.Top:= Y;
    AUnit.Width:= W;
    AUnit.Height:= H;
    AUnit.Caption:= inttostr(i);
    P:= X + W + S;
    if P < ATabSheet.ClientWidth then
     X:= P //X = X + Width + space
    else
    begin
     X:= 5;
     Y:= Y + H + S; //Y = Y + Hieght + Space
    end;
   end;
 except
 begin
  ShowMessage('Error retrieving units to display on location pages!');
 end;
 end;//try
end;

procedure TForm1.UpdateLocations;
var
 Locations: TStringList;
 I: Integer;
 APage: TTabSheet;
begin
 //RemoveLocations;
 //Locations:= TStringList.Create;
 //frmDataMod.GetLocations(Locations, False);
 for I:= 0 to 3 do
 begin
  APage:=  TTabSheet.Create(pgeMain);
  APage.PageControl:= pgeMain;
  APage.Parent:= pgeMain;
  APage.Caption:= 'tab' + IntToStr(i);
  UpdateUnits(APage);
 end;
 //Locations.Free;
end;

procedure TForm1.FormDblClick(Sender: TObject);
var
  aunit: Tpanel;
  atabsheet: ttabsheet;
begin
  UpdateLocations;
end;

end.

===============================

object Form1: TForm1
  Left = 273
  Top = 55
  Width = 783
  Height = 540
  Caption = 'Form1'
  Color = clBtnFace
  Font.Charset = DEFAULT_CHARSET
  Font.Color = clWindowText
  Font.Height = -11
  Font.Name = 'MS Sans Serif'
  Font.Style = []
  OldCreateOrder = False
  OnDblClick = FormDblClick
  PixelsPerInch = 96
  TextHeight = 13
  object pgeMain: TPageControl
    Left = 228
    Top = 108
    Width = 289
    Height = 193
    TabOrder = 0
  end
end

Open in new window

0
 
Looking_4_AnswersAuthor Commented:
thanks, but i believe i already stated above that i know that works.....im trying to figure out why my code doesn't work. Im headed to bed, its late here, i will wait to hear from other experts in the morning
0
 
cyberkiwiCommented:
I was using your code "that does not work" in my snippet, but let's see if anyone has any clues.
Did you try the ShowMessage?
0
 
cyberkiwiCommented:
ewangoya may just have your answer there.
I was most recently working in D5, so I was testing there.
If you are working with later/st versions with XP themes, then that would be the issue.

Link below for my own reference as well.

https://forums.codegear.com/thread.jspa;jsessionid=2CE3A47AFD8C54BEC6BD96A22BF71DED?messageID=183851𬸫
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.