【问题标题】:How do I programatically add actions to an Action Manager in Delphi 2010如何以编程方式将动作添加到 Delphi 2010 中的动作管理器
【发布时间】:2011-05-16 01:43:32
【问题描述】:

我正在尝试动态添加操作项,我可以添加该项目并且当我这样做时它可以工作:

HostActionItem := ActionManager.ActionBars[0].Items[0].Items[2];
  NewItem := HostAction.Items.Add;
  NewItem.Action :=  MyActionToPerform;
  NewItem.Caption := Description;
  NewItem.ImageIndex := 1;
  NewItem.Tag := 13;

但是,当动作 Execute 方法触发时,我尝试从 Sender 对象中获取 ActionComponent,如下所示:

  if (Sender is TAction) then
  tag := (Sender As TAction).ActionComponent.Tag;

但是 ActionComponent 总是为零。为什么 ActionComponent 没有被初始化?

【问题讨论】:

  • “为什么 ActionComponent 没有被初始化?” 似乎是这里真正的问题,而不是如何向动作管理器添加动作。顺便说一句,尝试使用操作Tag,如果您需要为同一操作使用不同的标签,那么您可能需要另一个操作,而不是创建"god" event handler
  • 抱歉,我的措辞使问题混淆了。本质上你是对的。我正在寻找一种具有动态操作的方法,因此需要一个相当灵活的事件处理程序。您是否建议也动态创建底层操作,或者有更好的方法来做到这一点?

标签: delphi delphi-2010 taction tactionmanager


【解决方案1】:

简短回答:

您希望 TActionClientItem 显示为 ActionComponentTAction。这不会发生,因为TActionClientItem 不是来自TComponent

更长的答案:

我相信您正在将您的项目添加到菜单栏。似乎是设计使链接到菜单项的TAction 不支持ActionComponent。菜单栏的项目类型为TActionClientItem。这是一个“收藏品”,而不是“组件”。因此在调用选中项的动作链接的Execute方法时,菜单不能用菜单项填写ActionComponent参数。如果这听起来令人困惑,我想 VCL 源代码中的以下引用会说明问题:

TBasicActionLink.Execute方法:

function Execute(AComponent: TComponent = nil): Boolean; virtual;

传递的组件在执行之前被分配给FAction.ActionComponent

如何从TCustomActionMenuBar.ExecAction调用:

FSelectedItem.ActionLink.Execute;

对于标题中的问题,我认为您没有做错任何事情,除了设置TActionClientItemCaptionImageIndex 是不必要的,因为它是TAction 的标题以及将要显示的图像。

【讨论】:

  • 感谢您的回答。我设置了标题、图像索引和标签,因为我对多个操作链接重复使用相同的操作。我这样做很难吗?有没有更好的方法来尝试实现动态操作项?
  • @Leigh - 我没有看到任何更简单的方法......添加一个客户项目并将其与一个动作相关联,就是这样。请注意,如果您重用操作,您将无法提供内置的自定义功能。如果您需要在 OnExecute 中区分来源,唯一的方法似乎是对每个项目使用一个操作。
  • 谢谢,我现在只为动态创建的项目维护单独的操作,它工作正常。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-20
  • 1970-01-01
  • 2016-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多