Search code examples
androiddelphiframefiremonkeytabcontrol

How do I make rectangle appear before and during loading frame into TabItem?


My project is for Android platform using Delphi. the project consists of:

  • Main form : It contains

    • TTabControl with 2 TTabItems : I placed on the first TabItem1 buttons ..
    • One Rectangle : I placed inside it Label1 with text 'Please wait ..', and set Visible property to False.
  • DataModule : SQLite Database, ...

  • One FireMonkey frame: it contains TListView to display data from sqlite db, ...

And the code is like this :

uses ... , Unit1;

...
private
  fFrame1: TFrame1;

...

procedure TMainForm.Button1Click(Sender: TObject);
begin
  if fFrame1 = nil then
  begin
    Rectangle1.Visible := True;
    fFrame1 := TFrame1.Create(Application);
    fFrame1.Parent := TabItem2;
    Rectangle1.Visible := False;
  end;
    TabControl1.ActiveTab := TabItem2;
end;

The Frame1 takes some time to load into TabItem2, but everything is done correctly.. The problem here is that the rectangle is not displayed before or during loading Frame1 .. I have tried many times but always the rectangle remains hidden and does not appear.

Any help..


Solution

  • Here is my suggestion including code to test with. The purpose of these extra steps, are to disconnect the button click (and display of the wait message) from the time consuming frame creation. As a result, the application has an opportunity to display the wait message between these to events.

    First, drop a TTimer on your form. You already have the rectangle with a label, and the other components. Here in my test I created a procedure SpendSomeTime(ms: integer); to simulate the delay of your frame creation.

    Then the Button1Click():

    procedure TForm36.Button1Click(Sender: TObject);
    begin
      Label1.Text := 'Please wait ...';
      Rectangle1.Visible := True; // show the please wait ... msg
      Timer1.Enabled := True;   // the Timer1.Interval is preset to 1 ms.
    end;
    

    The delay simulation procedure

    procedure TForm36.SpendSomeTime(ms: Integer);
    const
      ms1: double = 1 / 24 / 60 / 60 / 1000;
    var
      t: TTime;
    begin
      t := now + ms1 * ms ;
      repeat
      until now >= t;
    end;
    

    And OnTimer event, that first disables the timer, as we only want a one time event

    procedure TForm36.Timer1Timer(Sender: TObject);
    begin
      Timer1.Enabled := False;
      SpendSomeTime(3000);         // simulate the slow creation of the frame
      Rectangle1.Visible := False; // The frame creation returns and we can hide the message
    end;