Alex Kirov
Alex Kirov

Reputation: 217

Delphi- How to Call ActionList on button click?

I'm making a multi-device application in Delphi XE8 which uses LiveBindings to a dataset.

There are a number of LB-specific Actions for FMX, including TFMXBindNavigateDelete. I'm trying to use this in a button-click handler like this:

Button Click Code:

procedure TForm1.Button1Click(Sender: TObject);
begin
  if cdsOrdersSTATUS.Value='READY' then
  begin
    ShowMessage('Your Order Is Already READY/PENDING!');
  end
  else
  begin
    TAction(ActionList1.Actions[0]).Execute; //Not working,why?
  end;
end;

The first (and only) item in ActionList1's Actions is my FMXBindNavigateDelete1.

The problem is, even if the code TAction(ActionList1.Actions[0]).Execute executes, the current dataset record is not deleted, so apparently TFMXBindNavigateDelete's Action has no effect. Why is this, and how can I make it work?

Pic. ActionList1:

ActionList

Upvotes: 1

Views: 5201

Answers (2)

MartynA
MartynA

Reputation: 30715

Actually, I think this is a good question and doesn't deserve the downvote.

I can reproduce your problem. I put two buttons on the FMX form. I set Button1's OnClick to your Button1Click and Button2's Action to LiveBindingsBindNavigateDelete1.

Clicking Button2 pops up the standard 'Delete record?' confirmation and deletes the current record if I answer "Yes", as expected.

However, when clicking Button1, even if your else block executes, the 'Delete record?' confirmation does not appear, so the record has no chance of being deleted.

The reason is in the code

function TCustomAction.Execute: Boolean;
begin
  Result := False;
  if Supported and not Suspended then
  begin
    Update;
    if Enabled and AutoCheck then
      if (not Checked) or (Checked and (GroupIndex = 0)) then
        Checked := not Checked;
    if Enabled then
      Result := ((ActionList <> nil) and ActionList.ExecuteAction(Self)) or
        ((Application <> nil) and Application.ExecuteAction(Self)) or inherited Execute or
        ((Application <> nil) and Application.ActionExecuteTarget(Self));
  end;
end;

The Enabled property seems by default to be set to False during the call to Update so the if Enabled then ... never executes. I haven't managed to find a way to get Enabled set to True during the call to Update. Perhaps someone else knows how to do that.

In the case of Button2, execution then passes to TComponent.ExecuteAction and it is the call to Action.ExecuteTarget(Self) in it which results in the record-deletion routine executing.

So, from that, your problem seemed to me to become how to adjust the code so that TComponent.ExecuteAction gets executed, in other words, how to associate the Action with a component. The answer was fairly obvious.

All that's needed is this

procedure TForm1.Button1Click(Sender: TObject);
begin
 if cdsOrdersSTATUS.Value='READY' then
  begin
    ShowMessage('Your Order Is Already READY/PENDING!');
  end
  else
  begin
    Button1.ExecuteAction(LiveBindingsBindNavigateDelete1);  //  <- this works
    //LiveBindingsBindNavigateDelete1.Execute; //Not working,why?
  end;
end;

Upvotes: 5

SimaWB
SimaWB

Reputation: 9294

I didn't understand exactly what you wanted to do but if you trigger the action by it's index, you can do something like this:

TAction(ActionList1.Actions[0]).Execute;

Upvotes: 0

Related Questions