delphi - 如何在 ActionMainMenuBar 中禁用 menuitem 并停止下拉菜单?
问题描述
Delphi 10.4.2 我的 TActionMainMenuBar 有问题。当我在代码中禁用菜单项时,它显示为已禁用,但如果我在它旁边下拉启用的菜单项,然后移动到禁用的菜单项,它的子菜单会下拉!如果这不是错误,是否有办法防止禁用的菜单项下拉?
谢谢托尼
解决方案
一个简单的解决方案是在TActionMainMenuBar.OnPopup
禁用项目时关闭菜单:
procedure TForm1.ActionMainMenuBar1Popup(Sender: TObject; Item: TCustomActionControl);
begin
if not Item.Enabled then
ActionMainMenuBar1.CloseMenu;
end;
但是我不建议这样做,因为它也会退出菜单循环,这可能会导致糟糕的用户体验。
您描述的行为可以被视为缺陷,您可以将其报告给 Embarcadero。要在您的代码中解决此问题,您应该覆盖方法CreatePopup
以TActionMainMenuBar
防止nil
为禁用的项目创建弹出菜单(返回)。但是nil
在使用该方法打开子菜单时返回该方法会导致另一个问题(访问冲突)↑</kbd> or ↓</kbd> on keyboard. Therefore you should handle that case too by patching WMKeyDown
. Ideally you should derive your own class from TActionMainMenuBar
or use an 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;
推荐阅读
- sql - 如何在postgresql中使用查询结果提供的数据添加新列
- r - 函数每次都会覆盖同一个对象:我怎样才能避免这种情况?
- qt - TextArea QML 5.13 组件对于大文本非常慢
- bash - 管道 nginx -V 到 grep 的颜色不匹配
- python - 在尝试使用 train_test_split 时,我的测试集形状很奇怪
- android - 当 DynamoDB 中有任何插入时,如何在我的 Android 应用程序中获得通知?
- kotlin - 对列表的每个元素执行操作,返回一个 Flowable
- f# - 使用列表中的参数通过函数多次更新记录
- plotly-dash - 长时间运行时在浏览器上显示旋转的轮子/圆圈图像
- javascript - 在谷歌表单中按下提交按钮后如何使页面滚动到顶部?