Use TAction for an "icon only" TButton
Asked Answered
M

3

5

I have a TAction that is used for both a menu item and a TButton. I want the menu item to show the label, and the TButton to show only the icon. However, when an Action is assigned, Vcl automatically sets the TButton's Caption attribute, and I cannot get rid of it.

Any ideas?

Marciamarciano answered 11/12, 2012 at 8:35 Comment(0)
V
6

On the menu item, set ImageIndex to -1. On the button, set the Caption to ''. You must do this at runtime.

This will break the association with the action for just those individual properties. The action will still be used for Hint, OnExecute, OnUpdate etc.

Vainglorious answered 11/12, 2012 at 9:2 Comment(0)
A
4

You could have two separate actions: one for the menu item, one for the button.

Apuleius answered 11/12, 2012 at 9:39 Comment(9)
It is a possibiliy, but it ignores the principle of actions.Highspirited
@Highspirited I don't think so. For example, they could both share the same handlers for OnExecute and OnUpdate events.Apuleius
Yes, a Button and a MenuItem could share an OnClick handler as well. The principle of action is to define a piece of code, without caring about which control or controls execute them. You want (amongst others) to be able to disable just that action, not having to worry about other actions doing the same thing.Highspirited
Yes, and there's no conflict with any "principle of actions". If two or more actions share the same OnExecute and OnUpdate handlers you still don't care which control executes them. You can (amongst others) disable just those actions, in one place, in the shared OnUpdate handler and don't have to worry about anything.Apuleius
A slight variation of TOndrej's technique is to layer the two actions. Proceed as TOndrej's suggestion of two actions - one for the button and one for the menu item, but consider one action to be 'higher' than the other. Instead of directly sharing event handlers, let the higher action's event handler invoke the lower one. In an immediate sense, the outcome is the same. But it gives you one more degree of separation, offering cheaper extensibility.Lotson
Actually, having two actions that do the same thing does break the principle of actions. When you enable/disable actions in the TActionList's OnUpdate handler (as you should), you now have two actions to worry about instead of one. If you would like more info on why and how you should use the TActionList's OnUpdate handler, check out Ray Konopka's (yes, author of the Raize components) excellent article on them: Effectively using Action ListsForecourt
@MarjanVenema It's not clear from your comment what you mean by "principle of actions" and how this breaks it. BTW, I don't agree with your assertion that one should use TActionList's OnUpdate handler. I agree with Ray that sometimes it may be easier to manage, depending on the application context.Apuleius
@TOndrej: principle of actions in my mind = one TAction manages the visibility, enabledness etc. of a single user action. Ok, 'should' may be a bit strong, but I have found that concentrating the logic for what's available through the user interface in one handler greatly improves manageability and maintainability of the interrelationships of all user actions.Forecourt
@MarjanVenema Well, based on that definition, I agree with you, this breaks it. ;-) Thanks for taking the time to explain it.Apuleius
U
3

A more hacky solution could be setting the TAG 22 to e.g. in following Example

type

  TButton=Class(Vcl.StdCtrls.TButton)
         procedure SetText(var Message:TWMSETTEXT); message WM_SETTEXT;
  End;

  TForm4 = class(TForm)

    ActionList1: TActionList;
    ImageList1: TImageList;
    Action1: TAction;
    BitBtn1: TBitBtn;
    Button1: TButton;
    Button2: TButton;
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form4: TForm4;

implementation

{$R *.dfm}

{ TMyButton }

procedure TButton.SetText(var Message:TWMSETTEXT);
begin

  if Tag<>22 then   inherited else Message.Result := 1;
end;
Unseat answered 11/12, 2012 at 9:33 Comment(1)
I'm not sure I would use this hacky method, but I like the principle of making the button handle the text property differently. A cleaner alternative would be to use some kind of a TIconButton that only displays the image and uses the Text property as a hint (or not at all, since the Action has a hint as well). But in general, I think this is the best solution.Highspirited

© 2022 - 2024 — McMap. All rights reserved.