【问题标题】:How to disable menuitem and stop dropdown in ActionMainMenuBar?如何在 ActionMainMenuBar 中禁用 menuitem 并停止下拉菜单?
【发布时间】:2021-05-10 05:18:55
【问题描述】:

德尔福 10.4.2 我的 TActionMainMenuBar 有问题。当我在代码中禁用菜单项时,它显示为已禁用,但如果我在它旁边下拉启用的菜单项,然后移动到禁用的菜单项,它的子菜单会下拉! 如果这不是错误,有没有办法防止禁用的菜单项下拉?

谢谢 托尼

【问题讨论】:

  • this 对您有帮助吗?
  • 我看不到。那是 VB 和一个不同的组件。
  • 如果禁用 menuitem 并循环遍历它的子项,将它们设置为不可见会发生什么?我的想法是,一个可见子项为零的菜单项不会下拉?
  • 感谢您的建议。如果出现更多问题,将进一步研究此选项。

标签: delphi menuitem


【解决方案1】:

一个简单的解决方案是在项目被禁用时关闭TActionMainMenuBar.OnPopup 事件中的菜单:

procedure TForm1.ActionMainMenuBar1Popup(Sender: TObject; Item: TCustomActionControl);
begin
  if not Item.Enabled then
    ActionMainMenuBar1.CloseMenu;
end;

但我不建议这样做,因为它还会退出菜单循环,这可能会导致糟糕的用户体验。

您描述的行为可以被视为缺陷,您可以report it to Embarcadero。要在您的代码中解决此问题,您应该覆盖 TActionMainMenuBar 的方法 CreatePopup,以防止为禁用的项目创建弹出菜单(返回 nil)。但是在该方法中返回nil 会在使用键盘上的 打开子菜单时导致另一个问题(访问冲突)。因此,您也应该通过修补WMKeyDown 来处理这种情况。理想情况下,您应该从TActionMainMenuBar 派生您自己的类或使用interposer class

type
  TActionMainMenuBar = class(Vcl.ActnMenus.TActionMainMenuBar)
  private
    procedure WMKeyDown(var Message: TWMKeyDown); message WM_KEYDOWN;
  protected
    function CreatePopup(AOwner: TCustomActionMenuBar;
      Item: TCustomActionControl): TCustomActionPopupMenu; override;
  end;

{ ... }


function TActionMainMenuBar.CreatePopup(AOwner: TCustomActionMenuBar;
  Item: TCustomActionControl): TCustomActionPopupMenu;
begin
  if Item.Enabled then
    Result := inherited CreatePopup(AOwner, Item)
  else
    Result := nil;
end;

procedure TActionMainMenuBar.WMKeyDown(var Message: TWMKeyDown);
begin
  if Assigned(Selected) and (not Selected.Control.Enabled) and
     (Orientation in [boLeftToRight, boRightToLeft]) and
     (Message.CharCode in [VK_UP, VK_DOWN]) then
    Exit; { do not try to popup disabled items }
  inherited;
end;

【讨论】:

  • 谢谢彼得。同时我尝试将菜单项操作设置为 visible=false 但它仍然出现!我添加了一个 onEnter 事件,但我无法让它执行 - 有什么想法吗?似乎附加到带有子项的菜单项的操作也不会执行。
  • @Tony 设置操作可见性对我有用,至少在 10.3.3 中。您确定要设置与顶级菜单项相关的操作的可见性吗?顶级项目通常不连接到操作,因为它们通常是通过从TActionManager 设计器拖放整个类别来创建的。为什么要使用OnEnter 事件?无论如何,这些都是与原始问题无关的新问题。让我们专注于我提供的答案。您是否尝试过建议的修复?
  • 谢谢我根据您的建议创建了一个插入器类,它修复了下拉问题。 (如果触发了 onenter 事件,那么在菜单中配置子项会很有用)
  • 您可以使用在显示子菜单之前发生的OnPopup 事件中的项目进行操作。还有OnEnterMenuLoop 事件,每次在菜单循环中第一次激活项目时都会发生。一如既往remember to accept/upvote the answer,如果它有用并帮助您解决问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-08
  • 1970-01-01
  • 2021-11-30
  • 2016-04-13
  • 2013-12-19
  • 2022-11-14
相关资源
最近更新 更多