Question

I want to create a single window application where several panels can be accessed from a small menu. I want to slide the panels in from one side.

I have done a small demo application and everything works. The only problem is, that i have about 7 panels in one form for my demo app. Its hard to keep an overview over those panels and to change them, because they are all on top of each other.

So i wanted to create an extra unit for each panel, where i can design and change the panels like i want and then add them to the main form with code.

I looked into a forms fmx file and create one for a panel, also i created a .pas for the panel.

Unit2.pas:

unit Unit2;

interface

uses ...

type
  TPanel1 = class(TPanel)
  Label1: TLabel;
end;
var
  Panel1: TPanel1;

implementation
{$R *.fmx}

end.

Unit2.fmx:

object Panel1: TPanel1
  Left = 0
  Top = 0
  Caption = 'Panel1'
  ClientHeight = 551
  ClientWidth = 800
  Visible = False
  StyleLookup = 'backgroundstyle'
  object Label1: TLabel
    Position.Point = '(8,8)'
    Width = 120.000000000000000000
    Height = 15.000000000000000000
    TabOrder = 9
    Text = 'Panel1'
  end
end

I can now use the designer to design my panel. But when i want to use it in the main form by doing something like:

Panel1 := TPanel1.Create(Self);
Panel1.Parent := Self;

I only get an standard TPanel, not the one that I designed.

When i keep everything the same and just change the base class from TPanel to TForm it works like expected (.Show instead of .Parent= of course to test).

What do I have to do, to get my designed panel into the main form?

Thanks for any help.

Was it helpful?

Solution

The way I would do this is to use what I call embedded forms, which is the FireMonkey equivalent of frames.

For each of your panels, create a form, and add a panel to it:

type TPanelForm1 = class(TForm)
  Panel1: TPanel;
  ...

Place you controls inside the panel.

In your main form, instantiate each form, and fetch it's panel:

procedure TForm1.FormCreate(Sender: TObject);
begin
  PF1 := TPanelForm1.Create(Self);
  PF1.Panel1.Parent := Self;
  PF1.Position := ...
  PF1.Align := ...
end;

(Set Position and Align properties as required).

Note that if the panels are small you can add a number of them to a single form and set each Parent individually, for larger panels or for better modularity add one to each form.

OTHER TIPS

TPanel doesn't know how to load subcomponents from a form resource. That's what makes forms and frames special. If you don't have access to frames, then you can create all the subcomponents in code instead. You can use GExperts to help you get started. Create a new form and design it the way you'd like your panel to look. Select all the components on it, and use the GExperts "components to code" tool. That will place some code on the clipboard. Open your panel unit, and in the constructor, paste the generated code.

constructor TPanel1.Create(AOwner: TComponent);
begin
  inherited;

  // paste GExperts-generated code here
end;

The code will refer to fields that don't exist in TPanel1 yet, so go declare the missing fields in the class declaration. Now you can discard the form you were designing, or else you can save it for future design modifications. Just paste the changes over the previous code.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top