delphifiremonkeytframe

Delphi Frame inherited property does not exist


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 :

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

Solution

  • 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