I want to write some code that assigns the same event handler to several different buttons. Is there a way to implement it without referring to each button by name but by using something generic like self or sender to refer to the button?
views:
185answers:
4Yes. Every normal method call includes a hidden "Self" that refers to the object. But in an event handler, "Self" is the form, not the button. The button is Sender, and you'll have to typecast it using something like Sender as TButton
.
You'll need to use sender.
(Sender as TButton).Enabled := False;
Would disable any button that has this event handler assigned to its onclick event. The cast can also be done
TButton(Sender).Enabled := False;
but in this case you need to be 100% that sender is a button. Using as introduces a check before the cast, so is slightly slower, but in this type of example is not really a problem I think.
You can do something like this:
procedure OnClickButton(Sender: TObject);
var btn: TButton;
begin
if Sender is TButton then btn := TButton(mycontrol)
else
exit;
//and then use btn as just another button control
end;
and to assign the same event to different controls you could do:
if mycontrol is TButton then
TButton(mycontrol).OnClick := OnClickButton;
Consider 'disconnecting' yourself from buttons and use actions. Plonk an action list on your form, right-click it and 'add' and action. Name it, caption it (as if it were a button, say) and then wire up its OnExecute event to your code. Finally, go to your button and click on the 'Action' property and nominate your new action. When you click on the button, your code is executed.
Why is this useful? Well: 1. You will not lose access to your code, which commonly happens when you delete the button and replace it with, say, a TPopupMenu. 2. One action can be launched with way from several places, multiple buttons or menus. 3. Better still, fill in the action's 'OnUpdate' event with something like:
procedure TForm1.MyActionOnUpdate( ASender : TObject );
begin
With Sender as TAction do
Enabled := ItsPossibleToRunMyCode;
end;
This bit of code will enable and disable any control that uses this action without you needing to do anything.