Delphi Frame inherited property does not exist

711 views Asked by At

In Firemonkey Delphi 10.3, I create a custom TFrame type to add fonctionnality :

  TCustomFrame = class(TFrame);

  TFrameObserver = class(TCustomFrame, IObserver)
  public
    procedure Update; virtual;
  end;

And then my frame inherit from this class :

  TfStore = class(TFrameObserver)

All was good, I save it and this morning I have the error message when I open in design time (same in exec time) :

Property fStore.Size.Width does not exist

When I ignore these error, I see that in .fmx, it remove the property :

Size.Width
Size.Height
Size.PlateformDefault

And add the :

ClientWidth
ClientHeight

If I do this, it's work :

TfStore = class(TFrame, IObserver)

Did I do something wrong ?

To reproduce :

  • Create a new Firemonkey Project

  • Add a TFrame that inherited from the test below :

    type IFrameTest = interface procedure Test; end; TFrameTest = class(TFrame);

    TFrameITest = class(TFrameTest, IFrameTest)
      procedure Test; virtual;
    end;
    
    TFrame1 = class(TFrameITest)
    private
      { Déclarations privées }
    public
      procedure Test; override;
    end;
    

Close and open project to have the error

Here is the code from my project:

unit Unit2;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, 
  FMX.Types, FMX.Graphics, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.StdCtrls;

type
  IFrameTest = interface
    procedure Test;
  end;

  TFrameTest = class(TFrame);

  TFrameITest = class(TFrameTest, IFrameTest)
    procedure Test; virtual;
  end;

  TFrame2 = class(TFrameITest)
  private
    { Déclarations privées }
  public
    procedure Test; override;
  end;

implementation

{$R *.fmx}

{ TFrameITest }

procedure TFrameITest.Test;
begin
  //
end;

{ TFrame2 }

procedure TFrame2.Test;
begin
  inherited;
  //
end;

end.

and the corresponding FMX file:

object Frame2: TFrame2
  Size.Width = 320.000000000000000000
  Size.Height = 240.000000000000000000
  Size.PlatformDefault = False
end
1

There are 1 answers

2
fpiette On BEST ANSWER

TFrame is a class for which special magic is done by the IDE.

To inherit a frame from another, first create your frame with the IDE, then create the inherited frame using the IDE (Menu file / New /other... / Inheritable items / select the first frame).

I see that you need an interface. Define it in the first (ancestor) frame and add it to the class declaration.

When you have the inherited frame, you can (not mandatory, depends on what you want to do) override the virtual methods implementing the interface.

Here is the code for the base frame (TFrame3) having an interface:

unit Unit3;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, 
  FMX.Types, FMX.Graphics, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.StdCtrls;

type
  IFrameTest = interface
    procedure Test;
  end;

  TFrame3 = class(TFrame)
  private
    { Private declarations }
  public
    procedure Test; virtual;
  end;

implementation

{$R *.fmx}

{ TFrame3 }

procedure TFrame3.Test;
begin
    ShowMessage('TFrame3.Test');
end;

end.

And the corresponding FMX file:

object Frame3: TFrame3
  Size.Width = 320.000000000000000000
  Size.Height = 240.000000000000000000
  Size.PlatformDefault = False
end

Here the code for the inheriting frame (TFrame4):

unit Unit4;

interface

uses
  System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, 
  FMX.Types, FMX.Graphics, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.StdCtrls,
  Unit3;

type
  TFrame4 = class(TFrame3)
  private
    { Private declarations }
  public
    procedure Test; override;
  end;

var
  Frame4: TFrame4;

implementation

{$R *.fmx}

{ TFrame4 }

procedure TFrame4.Test;
begin
    ShowMessage('TFrame4.Test');
end;

end.

And the corresponding FMX:

inherited Frame4: TFrame4
  Size.Width = 455.000000000000000000
  Size.Height = 337.000000000000000000
end