delphidelphi-xe3tactionmanager

How to add OnClick event on main menu (=Category, via TAction submenu) on ActionMainMenuBar?


I'm replacing my good old TMainMenu with TActionMainMenuBar but have some issues with it.

I'm currently using for my main menu items the 'OnClick' handler, but I can't find a way to reproduce the same behavior with TActionMainMenuBar.

For example, I create a TAction "Test" with category "Sample" and I drag/drop this on the TActionMainMenuBar. I can add code to the execute handler of the sub-menu "Test" because it has a TAction assigned to it, but I can't add event code to the main menu item "Sample" because it is just a Category / TActionClientItem of "Test" with no events.

I tried to assign an Action to this TActionClientItem, but Delphi XE3 is saying "You cannot set property ..." and when I click that it gives me a dialog "Actions not implemented for the current framework 'None'".

Another way would be two TActions, "Sample" and "Test" with "(no category)", but I can't drag/drop "Test" as sub-menu of "Sample" which I dropped on the TActionMenuBar before. It looks like I can only drag/drop main menu items, and not sub-menu items on an empty main menu item.


Solution

  • The purpose for using the main menu item's OnClick handler is usually to determine whether sub-menu items are enabled/disabled or visible. It's also usually where you enable/disable things like toolbar buttons that perform the same function:

    procedure TForm1.MyMainMenuItemClick(Sender: TObject);
    begin
      SomeMenuItem.Enabled := SomeConditionTest;
      SomeToolButton.Enabled := SomeMenuItem.Enabled;
      AnotherMenuItem.Enabled := AnotherConditionTest;
      AnotherToolButton.Enabled := AnotherMenuItem.Enabled;
    end;
    

    For TActionMainMenuBar items, you do this in the individual actions instead, in the OnUpdate event. The advantage of this is that when you enable/disable the action, all controls connected to the action are also enabled/disabled at the same time.

    procedure TForm1.SomeActionUpdate(Sender: TObject);
    begin
      SomeAction.Enabled := SomeConditionTest;  // Also controls the toolbutton
    end;
    
    procedure TForm1.AnotherActionUpdate(Sender: TObject);
    begin
      AnotherAction.Enabled := AnotherConditionTest; // Toolbutton too.
    end;
    

    The OnUpdate event is called just before the the child items are displayed, which is the same time that the old main menu item's OnClick would be called.