Question

In action bands there is a TAction component.

That component holds a property named

GroupIndex: Integer;

however the field

RadioItem: Boolean;

is not there.

  1. Why is that?
  2. How can I make a TAction to be a checkbox?

The orientation of the action is ActionMainMenuBar and ActionManager.

Was it helpful?

Solution

Though TAction descends from TComponent, an action is not a component in the sense of a GUI element. It is meant to be linked to a GUI element, which for instance can be a radio button, a checkbox, or in your case a TActionClientItem on a TActionMainMenuBar.

As for your questions:

  1. The GroupIndex property of an action indicates whether the action behaves like a radio item. The help says:

    GroupIndex is used to define groups of actions that act like radio buttons. When GroupIndex is greater than 0, it identifies the group to which the action belongs. When the Checked property of any action in that group is set to true, the Checked property of all other actions in the group is set to false. That is, only one action in the group can be checked at a time. Note: All actions in a group must be listed by the same action list or action manager.

  2. To show a menu item (a TActionClientItem) in an ActionMainMenuBar with a checkbox:

    • Create an action,
    • Set Checked to True,
    • Set the Category property,
    • Drag the category to the ActionMainMenuBar,
    • Ét voila.
    • Toggle the Checked property in the action's OnExecute event handler.

    To show a normal checkbox which is linked to an action in the ActionManager: do not use an ActionMainMenuBar, but an ActionToolBar on which you can drop the default checkbox component.

OTHER TIPS

I'm not sure if you want checkboxes or radio buttons, but both are easy: For example a simple VCL app with the following Form1.dfm:

object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 251
  ClientWidth = 588
  Color = clBtnFace
  ParentFont = True
  Menu = MainMenu1
  OldCreateOrder = False
  OnCreate = FormCreate
  PixelsPerInch = 96
  TextHeight = 13
  object CheckBox1: TCheckBox
    Left = 216
    Top = 32
    Width = 97
    Height = 17
    Action = Action1
    TabOrder = 0
  end
  object RadioGroup1: TRadioGroup
    Left = 336
    Top = 32
    Width = 185
    Height = 121
    Caption = 'RadioGroup1'
    Items.Strings = (
      '1'
      '2'
      '3')
    TabOrder = 1
  end
  object ActionList1: TActionList
    Left = 184
    Top = 120
    object Action1: TAction
      Caption = 'Action1'
      OnExecute = Action1Execute
    end
    object Action2: TAction
      Caption = 'Action2'
      GroupIndex = 1
      OnExecute = Action1Execute
    end
    object Action3: TAction
      Caption = 'Action3'
      GroupIndex = 1
      OnExecute = Action1Execute
    end
    object Action4: TAction
      Caption = 'Action4'
      GroupIndex = 1
      OnExecute = Action1Execute
    end
  end
  object MainMenu1: TMainMenu
    Left = 224
    Top = 120
    object miTest: TMenuItem
      Caption = 'Test'
      object miAction1: TMenuItem
        Action = Action1
        AutoCheck = True
      end
      object miSep: TMenuItem
        Caption = '-'
      end
      object miAction2: TMenuItem
        Action = Action2
        AutoCheck = True
        GroupIndex = 1
        RadioItem = True
      end
      object miAction3: TMenuItem
        Action = Action3
        AutoCheck = True
        GroupIndex = 1
        RadioItem = True
      end
      object miAction4: TMenuItem
        Action = Action4
        AutoCheck = True
        GroupIndex = 1
        RadioItem = True
      end
    end
  end
end

with these event handlers:

procedure TForm1.Action1Execute(Sender: TObject);
var
  actn: TAction absolute Sender;
begin
  Assert(Sender is TAction);
  actn.Checked := not actn.Checked;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  i: Integer;
begin
  // Hardcoded association for test purposes:
  for i := 0 to Pred(RadioGroup1.ControlCount) do
    RadioGroup1.Controls[i].Action := ActionList1.Actions[i + 1];
end;

works like one would expect for me.

To make the actions look like radio items on the menu, one has to set RadioItem on the menu items, not on the action. I don't know why this is not the default if GroupIndex is <> 0.

Update: The ActionManager stuff is trickier than good old ActionLists. This DFM

object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 271
  ClientWidth = 588
  Color = clBtnFace
  ParentFont = True
  OldCreateOrder = False
  OnCreate = FormCreate
  PixelsPerInch = 96
  TextHeight = 13
  object CheckBox1: TCheckBox
    Left = 200
    Top = 48
    Width = 97
    Height = 17
    Action = Action1
    TabOrder = 0
  end
  object RadioGroup1: TRadioGroup
    Left = 336
    Top = 32
    Width = 185
    Height = 121
    Caption = 'RadioGroup1'
    ItemIndex = 1
    Items.Strings = (
      '1'
      '2'
      '3')
    TabOrder = 1
  end
  object ActionMainMenuBar1: TActionMainMenuBar
    Left = 0
    Top = 0
    Width = 588
    Height = 24
    UseSystemFont = False
    ActionManager = ActionManager1
    Caption = 'ActionMainMenuBar1'
    ColorMap.HighlightColor = clWhite
    ColorMap.BtnSelectedColor = clBtnFace
    ColorMap.UnusedColor = clWhite
    ParentFont = True
    PersistentHotKeys = True
    Spacing = 0
  end
  object ActionManager1: TActionManager
    ActionBars = <
      item
        Items = <
          item
            Items = <
              item
                Action = Action1
                Caption = '&Action1'
              end
              item
                Caption = '-'
              end
              item
                Action = Action2
                Caption = 'A&ction2'
              end
              item
                Action = Action3
                Caption = 'Ac&tion3'
              end
              item
                Action = Action4
                Caption = 'Act&ion4'
              end>
            Caption = 'T&est'
          end>
        ActionBar = ActionMainMenuBar1
      end>
    Left = 184
    Top = 160
    StyleName = 'XP Style'
    object Action1: TAction
      Category = 'Test'
      AutoCheck = True
      Caption = 'Action1'
    end
    object Action2: TAction
      Category = 'Test'
      AutoCheck = True
      Caption = 'Action2'
      GroupIndex = 1
    end
    object Action3: TAction
      Category = 'Test'
      AutoCheck = True
      Caption = 'Action3'
      Checked = True
      GroupIndex = 1
    end
    object Action4: TAction
      Category = 'Test'
      AutoCheck = True
      Caption = 'Action4'
      GroupIndex = 1
    end
  end
end

with this handler

procedure TForm1.FormCreate(Sender: TObject);
var
  i: Integer;
begin
  for i := 0 to Pred(ActionManager1.ActionCount) do
    TAction(ActionManager1.Actions[i]).DisableIfNoHandler := False;
  for i := 0 to Pred(RadioGroup1.ControlCount) do
    RadioGroup1.Controls[i].Action := ActionManager1.Actions[i + 1];
end;

works. However I can't get the radio items to work without using AutoCheck.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top