I am trying to dynamically add actionitems, I can add the item and it works when I do this:
HostActionItem := ActionManager.ActionBars[0].Items[0].Items[2];
NewItem := HostAction.Items.Add;
NewItem.Action := MyActionToPerform;
NewItem.Caption := Description;
NewItem.ImageIndex := 1;
NewItem.Tag := 13;
However, when the action Execute method fires I attempt to get the ActionComponent from the Sender object like this:
if (Sender is TAction) then
tag := (Sender As TAction).ActionComponent.Tag;
But the ActionComponent is always nil. Why is the ActionComponent not being initialised?
short answer:
You’re expecting a
TActionClientItemto show up asActionComponentof anTAction. That won’t happen sinceTActionClientItemdoes not descend fromTComponent.longer answer:
I believe you’re adding your item to a menu bar. It seems to be by design that an
TActionlinked to a menu item would not support theActionComponent. The items of a menu bar is of typeTActionClientItem. This is a ‘collection item’, not a ‘component’. Hence the menu cannot fill in theActionComponentparameter with the menu item when calling theExecutemethod of the action link of the selected item. If this sounds confusing, I guess the below quotes from the VCL source would make it clear:TBasicActionLink.Executemethod:The passed component is assigned to
FAction.ActionComponentbefore it is executed.How it’s called from
TCustomActionMenuBar.ExecAction:For the question in the title, I don’t think you’re doing anything wrong, apart from setting the
CaptionandImageIndexof aTActionClientItemis unnecessary, as it’s theTAction‘s title and image which will be shown.