You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用ActionMainMenuBar和ActionManager实现TMainMenu的自动隐藏重复分隔符功能?

实现ActionMainMenuBar与ActionManager的重复分隔符自动隐藏功能

ActionMainMenuBar本身没有内置类似TMainMenu.AutoLineReduction的属性,我们可以通过以下两种实用方式实现相同效果:

方法一:手动触发分隔符清理

编写通用的清理函数,在修改菜单项可见性后调用,递归清理所有层级菜单中的重复/无效分隔符:

清理函数实现

procedure CleanupSeparators(AMenuItem: TCustomActionMenuBarItem);
var
  I: Integer;
  PrevIsSeparator: Boolean;
begin
  PrevIsSeparator := False;
  // 从后往前遍历,避免删除项时索引错乱
  I := AMenuItem.Count - 1;
  while I >= 0 do
  begin
    if AMenuItem.Items[I] is TSeparatorItem then
    begin
      // 移除连续分隔符、菜单首尾的分隔符
      if PrevIsSeparator or (I = 0) or (I = AMenuItem.Count - 1) then
        AMenuItem.Items[I].Free
      else
        PrevIsSeparator := True;
    end
    else
    begin
      PrevIsSeparator := False;
      // 递归处理子菜单
      if AMenuItem.Items[I] is TCustomActionMenuBarItem then
        CleanupSeparators(TCustomActionMenuBarItem(AMenuItem.Items[I]));
    end;
    Dec(I);
  end;
end;

调用时机

在修改对应Action的Visible属性后,传入顶级菜单项执行清理:

// 示例:隐藏某个菜单项对应的Action
Action_Export.Visible := False;
// 清理主菜单的所有层级分隔符
CleanupSeparators(TCustomActionMenuBarItem(ActionMainMenuBar1.Items[0]));

方法二:自动关联ActionManager更新事件

利用ActionManager的OnUpdate事件,让菜单每次更新时自动执行分隔符清理,无需手动调用:

procedure TMainForm.ActionManager1Update(Sender: TObject);
var
  I: Integer;
begin
  // 遍历所有顶级菜单项,递归清理
  for I := 0 to ActionMainMenuBar1.Items.Count - 1 do
  begin
    if ActionMainMenuBar1.Items[I] is TCustomActionMenuBarItem then
      CleanupSeparators(TCustomActionMenuBarItem(ActionMainMenuBar1.Items[I]));
  end;
end;

注意事项

  • 确保代码中引入了ActnMenus单元,否则TCustomActionMenuBarItem和TSeparatorItem会提示未定义。
  • 从后往前遍历菜单列表,是为了避免删除项时导致的索引偏移问题,保证清理逻辑准确。

内容的提问来源于stack exchange,提问作者Alex Egorov

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 00:40:43