When an action even fires, the "sender" is always the action itself. Usually that's the most useful, but is it somehow possible to find out who triggered the action's onexecute event?
Example
Let's say you have a form with the following:
- 2 buttons, called
Button1
andButton2
- 1 TAction called
actDoStuff
The same action is assigned to both buttons. Is it possible to show which button I clicked?
Example.dfm
object Form1: TForm1
object Button1: TButton
Action = actDoStuff
end
object Button2: TButton
Action = actDoStuff
Left = 100
end
object actDoStuff: TAction
Caption = 'Do Stuff'
OnExecute = actDoStuffExecute
end
end
Example.pas
unit Example;
interface
uses Windows, Classes, Forms, Dialogs, Controls, ActnList, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
actDoStuff: TAction;
procedure actDoStuffExecute(Sender: TObject);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.actDoStuffExecute(Sender: TObject);
begin
ShowMessage('Button X was clicked');
end;
end.
The only solution I see at the moment is to not use the action property of buttons, but having an eventhandler for each button, and calling actDoStuffExecute() from there, but that sort of defies the whole purpose of using actions in the first place.
I don't want to have a dedicated action for each separate control either. The example above is a simplified version of the problem that I'm facing. I have a menu with a variable number of menu items (file names), and each menu item basically has to do the same thing, except for loading another file. Having actions for each menu item would be a bit silly.
There are situations where the same action should apply to similar controls. The problem with
is that when the action is invoked by a say popup menu, you get the popup menu's name. You could use:
Instead of actions, just use a click event. Set all buttons to use the same event handler. Ideally, NOT named after the first button (you can rename it).
Here's the code:
Ok, in the meanwhile I think I found a workable solution..
I can have all controls use the same action; I just need to override their OnClick event handler, and I just need a single handler for all of them.
I'm still interested to know if it's possible to find out which control triggered the action, but for my current application I'm using a solution that's similar to the code below:
set the Tag of the buttons as 1, 2, ... etc and then:
Try using the ActionComponent property:
For example:
Using this I get "Button1" and "Button2" when I click the first and second button respectively.
Knowing what button triggered the action sort of goes against the point of using actions - an action may be triggered by a button click, or a menu click, or any number of other user activities. Actions exist to unify the state management of enable/disabled and click handling between buttons and menus.
If you want to know which button fired the action because you want to perform a slightly different operation, or "flavor" the operation differently, then perhaps TAction isn't the right solution for what you want to do.