Search code examples
androiddelphifiremonkey

How to confirm delete of a record in Delphi FMX Android


Typically in a Delphi VCL application which uses a TDataset descendent as data storage (eg TClientDataset), in the Dataset1BeforeDelete handler we do something like this:

procedure TClientModule1.MyCDSBeforeDelete(DataSet: TDataSet);
begin
  if MessageDlg('Delete?', mtCOnfirmation, [mbyes, mbNo], 0) <> mrYes then 
    SysUtils.Abort
end;

Now in a FMX application designed to run on Android, this becomes:

procedure TClientModule1.MyCDSBeforeDelete(DataSet: TDataSet);
  MessageDlg('Delete?'
    ,
    TMsgDlgType.mtWarning, [TMsgDlgBtn.mbYes, TMsgDlgBtn.mbNo], 0,
    procedure(const AResult: TModalResult)
    begin
      if AResult <> mrYes then
        Abort;
    end
    );
end;

Except, that's not going to work! The messagedlg is going to hold the user's attention, but the event handler code is going to continue and allow the record to be deleted anyway.

What's the solution?


Solution

  • Because modal window and Message Box currently are not supported in FMX for Android you should use some kind of "dog-nail" solution

    Ad-Hoc solution #1, .

    In main form or in form which should open Modal window write code like:

    procedure TForm1.btnSelectClick(Sender: TObject);
    begin
      if fmSelect = nil then
        begin
          Application.CreateForm(TfmSelect, fmSelect);
          fmSelect.Callback := Yahoo;
        end;
      fmSelect.Show;
    end;
    
    procedure TForm1.Yahoo(ASelectedItem: String);
    begin
      ShowMessage(ASelectedItem);
    end;
    

    in fmSelect should be your message and buttons with options (like Yes, No, May be, Not today).

    in fmSelect form you should declare PUBLIC variable Callback: TCallback;

    Once user press some button, you should call this function and close form:

    procedure TfmSelect.btnSelectClick(Sender: TObject);
    begin
      if Assigned(Callback) then
          Callback('user press button XXX');
    
      Close;
    end;
    

    TCallback just regular function which return String type (you could change it to Integer).

    TCallback = procedure (ASelected: String) of object;
    

    Ad-Hoc solution #2

    simulat to first, but with using hidden TComboBox. In combobox items will be stored all options, like "Yes", "No", "Maybe tomorrow". Once ComboBox was closed OnClosePopup event, you get value of user choise.

    enter image description here

    3. Take a look how it's done somewhere in Embarcadero samples (from XE8):

    http://docwiki.embarcadero.com/RADStudio/XE8/en/Mobile_Tutorial:_Using_FireDAC_and_SQLite_%28iOS_and_Android%29

    So in your case will be

    private
        procedure FCloseDialogProc(const AResult: TModalResult);
    
    
    procedure TForm1.Button1Click(Sender: TObject);
    begin
        MessageDlg('Want something', TMsgDlgType.mtWarning, [TMsgDlgBtn.mbYes, TMsgDlgBtn.mbNo], 0, FCloseDialogProc);
    end;
    
    procedure TForm1.FCloseDialogProc(const AResult: TModalResult);
    begin
        Label1.Text := IntToStr(AResult);
    
      // -1 -- click outside
      // 6 -- yes
      // 7 -- no
    end;