动态创建子菜单
Dynamically create submenu
我有一个带有名为 mnuWindows 的菜单项的 TMainMenu。我希望动态创建子菜单项。我认为这段代码可以做到,但它不起作用:
var
mnuitm: TMenuItem;
mnuitm:=TMenuItem.Create(nil);
mnuitm.Text:='some text';
mnuWindows.AddObject(mnuitm);
当我点击 mnuWIndows 时,没有任何反应。我哪里错了?
编辑:
子菜单在点击时没有显示,因为每次我这样做时,程序都是全新启动的,我没有意识到在这种情况下,两次点击是必要的。第一次点击并没有明显地做任何事情,第二次点击下拉子菜单。所以,我承认上面的代码片段有效。
但是我还是有困难。我需要创建几个子菜单项,所以我在 mnuWindows OnClick 事件处理程序中尝试了以下循环:
for I := 0 to TabSet1.Tabs.Count - 1 do
begin
mnuitm := TMenuItem.Create(mnuWindows);
mnuitm.Text := TabSet1.Tabs[I].Text;
mnuitm.OnClick:=MenuItemClick;
if not mnuWindows.ContainsObject(mnuitm) then
mnuWindows.AddObject(mnuitm);
end;
以上代码的目的是单击 mnuWindows 项目显示选项卡集中的选项卡列表。这段代码在一定程度上起作用。第一次点击时,它会正确列出当前选项卡。但是当我添加一个选项卡并再次单击 mnuWindows 时,新选项卡没有显示在列表中。该列表与以前完全相同。我想知道菜单是否需要以某种方式更新或刷新。我遇到了以下方法
IFMXMenuService.UpdateMenuItem(IItemsContainer, TMenuItemChanges)
但它的文档很少,我不确定如何使用它,甚至不确定它是否相关。
编辑2:
我认为对我的 post 的两次反对票是严厉的。我在网上广泛搜索了如何在 Firemonkey 中动态创建子菜单的示例,但搜索结果很少。我确实找到了 a solution from 2012,但此后的语法更改意味着它在 Tokyo 10.2 中不起作用。
尝试这样的事情。正如其他人在上面评论的那样,您需要提供一个在单击菜单项时会发生的事件。另请注意,我这里的方法需要一堆参数。如果我创建一个 class 并以这种方式传递详细信息,它会更干净,但我很久以前就写了这个,现在我的代码中有很多地方以这种形式使用它。另外,如果我现在写这个,我会使用一个函数来 return 创建的菜单项,以防我在特定情况下需要与之交互(例如,检查它,分配热键等)
procedure PopMenuAddItem(menu: TPopupMenu; sText: string; iID: integer;
clickEvent: TNotifyEvent; bEnabled: boolean = true);
var
NewMenuItem: TmenuItem;
begin
NewMenuItem := TmenuItem.create(menu);
with NewMenuItem do
begin
Caption := sText;
tag := iID;
Enabled := bEnabled;
OnClick := clickEvent;
end;
menu.Items.Add(NewMenuItem);
end;
procedure PopMenuAddSubItem(menuItem: TmenuItem; sText: string; iID: integer;
clickEvent: TNotifyEvent; bEnabled: boolean = true);
var
NewMenuItem: TmenuItem;
begin
NewMenuItem := TmenuItem.create(menuItem);
with NewMenuItem do begin
Caption := sText;
tag := iID;
Enabled := bEnabled;
OnClick := clickEvent;
end;
menuItem.Add(NewMenuItem);
end;
我已经回答了我自己的问题。
提醒一下,我想做的是在我的顶级菜单项 "Windows"(组件名称 "mnuWindows")下动态创建一个子菜单。在子菜单中,我希望列出标签集中标签的名称。
尝试在 mnuWindows.OnClick 事件中动态创建子菜单失败。
我最终的解决方案是使用以下方法重建子菜单,并在创建新选项卡、删除选项卡或重命名选项卡后立即调用此方法:
procedure Form1.ReBuildWindowsMenu;
var
mnuitm: TMenuItem;
I: Integer;
begin
mnuWindows.Clear; // removes submenu items
for I := 0 to TabSet1.Tabs.Count - 1 do
begin
mnuitm := TMenuItem.Create(MainMenu1);
mnuitm.Caption:= TabSet1.Tabs[I].Text; // submenu item displays same text as associated tab
mnuitm.OnClick := MenuItemClick; // makes the associated tab active
mnuWindows.AddObject(mnuitm);
end;
end;
OnClick 处理程序包含单个语句
TabSet1.ActiveTabIndex:=(Sender as TMenuItem).Index;
这个简单的解决方案使我的 Windows 列表与选项卡集中的选项卡完美同步。我打算使用类似的方法将最近使用的 (MRU) 文件列表放入我的文件菜单中。
我有一个带有名为 mnuWindows 的菜单项的 TMainMenu。我希望动态创建子菜单项。我认为这段代码可以做到,但它不起作用:
var
mnuitm: TMenuItem;
mnuitm:=TMenuItem.Create(nil);
mnuitm.Text:='some text';
mnuWindows.AddObject(mnuitm);
当我点击 mnuWIndows 时,没有任何反应。我哪里错了?
编辑:
子菜单在点击时没有显示,因为每次我这样做时,程序都是全新启动的,我没有意识到在这种情况下,两次点击是必要的。第一次点击并没有明显地做任何事情,第二次点击下拉子菜单。所以,我承认上面的代码片段有效。
但是我还是有困难。我需要创建几个子菜单项,所以我在 mnuWindows OnClick 事件处理程序中尝试了以下循环:
for I := 0 to TabSet1.Tabs.Count - 1 do
begin
mnuitm := TMenuItem.Create(mnuWindows);
mnuitm.Text := TabSet1.Tabs[I].Text;
mnuitm.OnClick:=MenuItemClick;
if not mnuWindows.ContainsObject(mnuitm) then
mnuWindows.AddObject(mnuitm);
end;
以上代码的目的是单击 mnuWindows 项目显示选项卡集中的选项卡列表。这段代码在一定程度上起作用。第一次点击时,它会正确列出当前选项卡。但是当我添加一个选项卡并再次单击 mnuWindows 时,新选项卡没有显示在列表中。该列表与以前完全相同。我想知道菜单是否需要以某种方式更新或刷新。我遇到了以下方法
IFMXMenuService.UpdateMenuItem(IItemsContainer, TMenuItemChanges)
但它的文档很少,我不确定如何使用它,甚至不确定它是否相关。
编辑2: 我认为对我的 post 的两次反对票是严厉的。我在网上广泛搜索了如何在 Firemonkey 中动态创建子菜单的示例,但搜索结果很少。我确实找到了 a solution from 2012,但此后的语法更改意味着它在 Tokyo 10.2 中不起作用。
尝试这样的事情。正如其他人在上面评论的那样,您需要提供一个在单击菜单项时会发生的事件。另请注意,我这里的方法需要一堆参数。如果我创建一个 class 并以这种方式传递详细信息,它会更干净,但我很久以前就写了这个,现在我的代码中有很多地方以这种形式使用它。另外,如果我现在写这个,我会使用一个函数来 return 创建的菜单项,以防我在特定情况下需要与之交互(例如,检查它,分配热键等)
procedure PopMenuAddItem(menu: TPopupMenu; sText: string; iID: integer;
clickEvent: TNotifyEvent; bEnabled: boolean = true);
var
NewMenuItem: TmenuItem;
begin
NewMenuItem := TmenuItem.create(menu);
with NewMenuItem do
begin
Caption := sText;
tag := iID;
Enabled := bEnabled;
OnClick := clickEvent;
end;
menu.Items.Add(NewMenuItem);
end;
procedure PopMenuAddSubItem(menuItem: TmenuItem; sText: string; iID: integer;
clickEvent: TNotifyEvent; bEnabled: boolean = true);
var
NewMenuItem: TmenuItem;
begin
NewMenuItem := TmenuItem.create(menuItem);
with NewMenuItem do begin
Caption := sText;
tag := iID;
Enabled := bEnabled;
OnClick := clickEvent;
end;
menuItem.Add(NewMenuItem);
end;
我已经回答了我自己的问题。
提醒一下,我想做的是在我的顶级菜单项 "Windows"(组件名称 "mnuWindows")下动态创建一个子菜单。在子菜单中,我希望列出标签集中标签的名称。
尝试在 mnuWindows.OnClick 事件中动态创建子菜单失败。
我最终的解决方案是使用以下方法重建子菜单,并在创建新选项卡、删除选项卡或重命名选项卡后立即调用此方法:
procedure Form1.ReBuildWindowsMenu;
var
mnuitm: TMenuItem;
I: Integer;
begin
mnuWindows.Clear; // removes submenu items
for I := 0 to TabSet1.Tabs.Count - 1 do
begin
mnuitm := TMenuItem.Create(MainMenu1);
mnuitm.Caption:= TabSet1.Tabs[I].Text; // submenu item displays same text as associated tab
mnuitm.OnClick := MenuItemClick; // makes the associated tab active
mnuWindows.AddObject(mnuitm);
end;
end;
OnClick 处理程序包含单个语句
TabSet1.ActiveTabIndex:=(Sender as TMenuItem).Index;
这个简单的解决方案使我的 Windows 列表与选项卡集中的选项卡完美同步。我打算使用类似的方法将最近使用的 (MRU) 文件列表放入我的文件菜单中。