dmitrybv 3 Posted August 26 If a FMX Frame is created from a class that is a descendant of the TFrame class, the designer starts saving non-existent properties in the fmx file. For example, in my project, a frame saves the ClientHeight and ClientWidth properties in the file, although there are no such properties in the TFrame class. As a result, when trying to place a frame on a form, an error occurs: ‘Cannot paste a from or datamodule into another form or module’. When trying to create a Frame at run-time, an error occurs: Project Project1.exe raised exception class EReadError with message 'Property ClientHeight does not exist'. I attach screenshots and a demo project. unit UnitBaseFrame; interface uses SysUtils, System.Classes, System.StartUpCopy, FMX.Forms, FMX.TabControl; type { TBaseInTabFrame } TBaseInTabFrame = class(TFrame) private public constructor Create(AOwner: TComponent); override; destructor Destroy; override; end; implementation { TBaseInTabFrame } constructor TBaseInTabFrame.Create(AOwner: TComponent); begin inherited Create(AOwner); end; destructor TBaseInTabFrame.Destroy; begin inherited Destroy; end; end. unit UnitInheritedFrame; interface uses System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants, UnitBaseFrame, FMX.Types, FMX.Graphics, FMX.Controls, FMX.Forms, FMX.Dialogs, FMX.StdCtrls; type TInheritedFrame = class(TBaseInTabFrame) private { Private declarations } public { Public declarations } end; implementation {$R *.fmx} end. object InheritedFrame: TInheritedFrame Left = 0 Top = 0 ClientHeight = 480 ClientWidth = 640 FormFactor.Width = 320 FormFactor.Height = 480 FormFactor.Devices = [Desktop, iPhone, iPad] DesignerMasterStyle = 0 end 2024-08-26-FrameInheriting.zip Share this post Link to post
havrlisan 25 Posted August 26 (edited) Your fmx file is wrong: 26 minutes ago, dmitrybv said: object InheritedFrame: TInheritedFrame Left = 0 Top = 0 ClientHeight = 480 ClientWidth = 640 FormFactor.Width = 320 FormFactor.Height = 480 FormFactor.Devices = [Desktop, iPhone, iPad] DesignerMasterStyle = 0 end In the first line, it should be inherited instead of object. If it's inherited, it draws all the properties from the parent classes, but if it's an object, it won't inherit anything. I never investigated why it saves those properties, which are properties from TForm and not TFrame ones. Edit: to properly inherit an existing frame in the same project, right click the project in the Projects view, Add new > Other > Delphi (drop down in new window) > Inheritable Items. There you'll see your frames, and you'll only be able to Inherit them (other options Copy and Use will be disabled). Edited August 26 by havrlisan Added how to inherit Share this post Link to post
dmitrybv 3 Posted August 26 1. This file was created by RAD Studio designer. I did not modify it manually. 2. Why do I need inherited here if the base class - TBaseInTabFrame does not have an fmx file? 3. I created a new frame TInheritedFrame, then in the unit file UnitInheritedFrame, I changed the line TInheritedFrame = class(TFrame) to TInheritedFrame = class(TBaseInTabFrame), because I need to have several basic methods for all frames of my project in the base class TBaseInTabFrame. Share this post Link to post
havrlisan 25 Posted August 26 6 minutes ago, dmitrybv said: 1. This file was created by RAD Studio designer. I did not modify it manually. 2. Why do I need inherited here if the base class - TBaseInTabFrame does not have an fmx file? 3. I created a new frame TInheritedFrame, then in the unit file UnitInheritedFrame, I changed the line TInheritedFrame = class(TFrame) to TInheritedFrame = class(TBaseInTabFrame), because I need to have several basic methods for all frames of my project in the base class TBaseInTabFrame. 1. Correct, and RAD Studio correctly created the fmx file. However, you changed your class inheritance from TFrame to TBaseInTabFrame, and because of that the correct keyword becomes inherited, not object. RAD Studio cannot know what your intentions are, so you must change it manually. 2. Your TBaseInTabFrame should have an fmx file; that's how I've always done it. I suppose you just created a blank unit and declared it, but you should create the unit as a new FireMonkey Frame (that's an actual option in the Add New tab menu). That way frame inheritance will work properly. 3. Read the previous two statements, they explain why that's a wrong approach. Share this post Link to post
dmitrybv 3 Posted August 26 Yes, you are right. Changing the line object InheritedFrame: TInheritedFrame to inherited InheritedFrame: TInheritedFrame fixes the problem with the ClientHeight, ClientWidth properties in the fmx file. That is, Frames only support visual inheritance. Although for a Form, if there is no fmx file in the base form, it is not necessary to use inherited. Share this post Link to post
Rollo62 539 Posted August 26 I would recommend not to use frames visually in the IDE, but only insert them at runtime. That will prevent a lot of issues in the IDE designer. Of course you can edit the frame itself, like with any other form. But using this frame in the designer on another form requires the designer to handle everything properly, which is still quite fragile during development. Using in runtime only doesn't affect the designer and the IDE will stay much more stable. Share this post Link to post