(Delphi FMX) How can I refresh my Frame Object inside a TabControl.TabItem without losing control of the window?

  

This application is intended initially for a Windows environment.

While having used only the initial code on the link mentioned below, I had to resorted to replacing the code to accept TabControls/TabItems (FMX) and not using PageControls/TabSheet (VCL) from the link below. With intent to create the Frame with the ability to rebuild content inside of a TabItem (Freeing itself and then using the Construct/Create object approach inside of a procedure).

embarcadero.com (Replacing TabSheets with Frames – by Dan Miser)

Every time I use tiframe1 while having been using Frames since Delphi Seattle 10, I have become accustomed to the ability of using them dynamically. This is one of the approaches. (problem occurs to happen at frame.Free; ) This approach causes the Application to not respond to moving the Window or Exit/Close or anything having to do with the Window layer (including a menu bar).

Does this have anything to do with the fact that TFrames were originally made for VCL?

Project1.dpr

program Project1;

uses
System.StartUpCopy,
FMX.Forms,
Unit1 in ‘Unit1.pas’ {Form1},
frame1 in ‘frame1.pas’ {tiframe1: TFrame};

{$R *.res}

begin
Application.Initialize;
Application.CreateForm(TForm1, Form1);
Application.Run;
end.

Unit1.pas

unit Unit1;

interface

uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.Forms, FMX.Graphics, FMX.Dialogs, FMX.TreeView,
FMX.Layouts, FMX.Controls.Presentation, FMX.StdCtrls, FMX.TabControl, FMX.Edit;

type
TForm1 = class(TForm)
TabControl1: TTabControl;
TabItem1: TTabItem;
TabItem2: TTabItem;
procedure FormCreate(Sender: TObject);
procedure RefreshFrame();

private
{ Private declarations }
procedure CreateFrame(ATabitem: TTabItem);

function GetFrame(ATabitem: TTabItem): TFrame;
public
{ Public declarations }

end;

var
Form1: TForm1;

implementation

{$R *.fmx}

uses frame1;

type
TFrameClass = class of TFrame;

procedure TForm1.FormCreate(Sender: TObject);
begin
TabItem1.Tag := Integer(Ttiframe1);
CreateFrame(TabItem1);
end;

function TForm1.GetFrame(ATabitem: TTabItem): TFrame;
begin
if not Assigned(ATabitem) then
ATabitem := TabControl1.ActiveTab;
Result := nil;
if Assigned(ATabitem) and (ATabitem.ControlsCount > 0) and (ATabitem.Controls[0] is TFrame) then
Result := TFrame(ATabitem.Controls[0]);
end;

procedure TForm1.CreateFrame(ATabitem: TTabItem);
var
frame: TFrame;
begin
if GetFrame(ATabitem) = nil then
if ATabitem.Tag <> 0 then
begin
frame := TFrameClass(ATabitem.Tag).Create(Self);
frame.Parent := ATabitem;
end;
end;

procedure TForm1.RefreshFrame();
var
frame: TFrame;
begin
if Assigned(FindComponent(‘tiframe1’)) then //
begin
frame := FindComponent(‘tiframe1’) as TFrame;
frame.Free; //This is the cause of all the problems
frame := Ttiframe1.Create(Self);
frame.Parent := TabControl1;
end;
end;

end.

And don’t forget to create a Frame and using a Construct/Create as well as at the bottom (before “end.”) create an RegisterClass as well.

unit frame1;

interface

uses
System.SysUtils, System.Types, System.UITypes, System.Classes, System.Variants,
FMX.Types, FMX.Controls, FMX.TabControl, FMX.Forms, FMX.Layouts, FMX.Dialogs,
FMX.StdCtrls, FMX.Graphics, FMX.Controls.Presentation, FMX.Memo, FMX.Edit;

type
Ttiframe1 = class(TFrame)
Button1: TButton;

procedure Button1Click(Sender: TObject);
private
{ Private declarations }

public
{ Public declarations }
constructor Create(AOwner: TComponent); override;
end;

implementation

{$R *.fmx}

uses Unit1;

procedure Ttiframe1.Button1Click(Sender: TObject);
begin
Form1.RefreshFrame();
end;

constructor Ttiframe1.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
end;

initialization
RegisterClass(Ttiframe1);

end.

Now I am also looking to see if TabItems can be re-rendered to display anything new or updated (sort of in a Refresh or Application.ProcessMessages approach), in a similar fashion as a Constructor in a Frame could, effecting such elements as TLabel.Text or perhaps even a TEdit.Text. Inside the construct I have it fetch data from a db dynamically.

The reason for the replacement is that While using (TTreeView) inside of, Frame, inside a TabItem, or otherwise, causes similar occurrence without having a known cause to make the attention/focus away from the MainForm window when I should use the RefreshFrame;

Comments are closed.