如何以编程方式将子菜单添加到 TActionMainMenuBar?
How to add Submenus to TActionMainMenuBar programatically?
我一直在开发一个 VCL 程序,并且正在添加用于放置列出一组文件的 'Recent Files' 下拉子菜单的代码。对于这个程序,我已经填充了一个 tActionManager 和一个 tActionMainMenuBar。在标准 tMainMenu 组件中使用 tmenuitems 之前,我创建了类似的菜单,该组件在 FormCreate 事件过程中生成最近文件子菜单项的列表。但是,我不确定如何使用 Action 组件动态地执行此操作,并且没有找到任何示例作为模型。
任何人都可以提供一个如何完成的例子
为了说明这一点,我创建了一个简单的应用程序,其中包含一个作为 TActionMainToolBar 的操作管理器,并使用标准项目打开、另存为和退出(无分隔符)以及一个速度按钮添加了一个简单的文件菜单。
速度按钮添加了两个分隔符和一个文件操作,其 OnClick 事件如下所示...
procedure TForm1.SpeedButton1Click(Sender: TObject);
var
iActionClientItem : TActionClientItem;
iFileAction : TCustomAction;
begin
// Edit2.Text := BaseToBase( Edit1.Text, SpinEdit1.Value , SpinEdit2.Value );
ActionManager1.AddSeparator( ActionManager1.FindItemByAction(FileExit1), FALSE );
iActionClientItem := ActionManager1.AddSeparator( ActionManager1.FindItemByAction(FileExit1) );
iFileAction := TCustomAction.Create( self ); // we want to put in same collection
iFileAction.Caption := 'Fred';
// etc.. to build what is wanted
iActionClientItem := ActionManager1.AddAction( iFileAction, iActionClientItem ) ;
end;
运行 程序和打开文件菜单显示三个预期条目。单击按钮后(不要重复两次 - 演示它是如何工作的)你会得到两个分隔符和一个新的菜单子项,标题为 'Fred' 请注意,你可能需要给它一个唯一的如果您需要对其进行任何处理,请命名。
编辑
构建子菜单的方法基本相同,但有一个小技巧,即不通过操作管理器添加未使用且不可见的项目。不必以这种方式完成 - 这只是获得我们想要的东西的简单方法。
这段代码展示了如何实现:
procedure TForm1.SpeedButton1Click(Sender: TObject);
var
iActionClientItem : TActionClientItem;
iSubMenuItem : TActionClientItem;
iFileAction : TCustomAction;
iChildMenu : TActionBarItem;
begin
ActionManager1.AddSeparator( ActionManager1.FindItemByAction(FileExit1), FALSE );
iActionClientItem := ActionManager1.AddSeparator( ActionManager1.FindItemByAction(FileExit1) );
iFileAction := TCustomAction.Create( self ); // we want to put in same collection
iFileAction.Caption := 'Fred';
// etc.. to build what is wanted
iActionClientItem := ActionManager1.AddAction( iFileAction, iActionClientItem ) ;
//*********************************
// Build sub menu (from Fred) - stage 1 add the visual element - a new action bar
iChildMenu := ActionManager1.ActionBars.Add;
iActionClientItem.ChildActionBar := iChildMenu.ActionBar;
// we add a dummy entry that we can build from.
// We could set the properties manually, but when we use the action manager
// it does that automatically, so it is easier just to set this item to not visible
// then use action manager to do the rest.
iSubMenuItem := iActionClientItem.Items.Add;
iSubMenuItem.Visible := FALSE;
// Now the real build...
iFileAction := TCustomAction.Create( self ); // we want to put in same collection
iSubmenuItem := ActionManager1.AddAction( iFileAction, iSubMenuItem );
iSubmenuItem.Caption := 'Fred 1';
// etc
iFileAction := TCustomAction.Create( self ); // we want to put in same collection
iSubmenuItem := ActionManager1.AddAction( iFileAction, iSubMenuItem );
iSubmenuItem.Caption := 'Fred 2';
// etc
end;
我一直在开发一个 VCL 程序,并且正在添加用于放置列出一组文件的 'Recent Files' 下拉子菜单的代码。对于这个程序,我已经填充了一个 tActionManager 和一个 tActionMainMenuBar。在标准 tMainMenu 组件中使用 tmenuitems 之前,我创建了类似的菜单,该组件在 FormCreate 事件过程中生成最近文件子菜单项的列表。但是,我不确定如何使用 Action 组件动态地执行此操作,并且没有找到任何示例作为模型。
任何人都可以提供一个如何完成的例子
为了说明这一点,我创建了一个简单的应用程序,其中包含一个作为 TActionMainToolBar 的操作管理器,并使用标准项目打开、另存为和退出(无分隔符)以及一个速度按钮添加了一个简单的文件菜单。
速度按钮添加了两个分隔符和一个文件操作,其 OnClick 事件如下所示...
procedure TForm1.SpeedButton1Click(Sender: TObject);
var
iActionClientItem : TActionClientItem;
iFileAction : TCustomAction;
begin
// Edit2.Text := BaseToBase( Edit1.Text, SpinEdit1.Value , SpinEdit2.Value );
ActionManager1.AddSeparator( ActionManager1.FindItemByAction(FileExit1), FALSE );
iActionClientItem := ActionManager1.AddSeparator( ActionManager1.FindItemByAction(FileExit1) );
iFileAction := TCustomAction.Create( self ); // we want to put in same collection
iFileAction.Caption := 'Fred';
// etc.. to build what is wanted
iActionClientItem := ActionManager1.AddAction( iFileAction, iActionClientItem ) ;
end;
运行 程序和打开文件菜单显示三个预期条目。单击按钮后(不要重复两次 - 演示它是如何工作的)你会得到两个分隔符和一个新的菜单子项,标题为 'Fred' 请注意,你可能需要给它一个唯一的如果您需要对其进行任何处理,请命名。
编辑
构建子菜单的方法基本相同,但有一个小技巧,即不通过操作管理器添加未使用且不可见的项目。不必以这种方式完成 - 这只是获得我们想要的东西的简单方法。
这段代码展示了如何实现:
procedure TForm1.SpeedButton1Click(Sender: TObject);
var
iActionClientItem : TActionClientItem;
iSubMenuItem : TActionClientItem;
iFileAction : TCustomAction;
iChildMenu : TActionBarItem;
begin
ActionManager1.AddSeparator( ActionManager1.FindItemByAction(FileExit1), FALSE );
iActionClientItem := ActionManager1.AddSeparator( ActionManager1.FindItemByAction(FileExit1) );
iFileAction := TCustomAction.Create( self ); // we want to put in same collection
iFileAction.Caption := 'Fred';
// etc.. to build what is wanted
iActionClientItem := ActionManager1.AddAction( iFileAction, iActionClientItem ) ;
//*********************************
// Build sub menu (from Fred) - stage 1 add the visual element - a new action bar
iChildMenu := ActionManager1.ActionBars.Add;
iActionClientItem.ChildActionBar := iChildMenu.ActionBar;
// we add a dummy entry that we can build from.
// We could set the properties manually, but when we use the action manager
// it does that automatically, so it is easier just to set this item to not visible
// then use action manager to do the rest.
iSubMenuItem := iActionClientItem.Items.Add;
iSubMenuItem.Visible := FALSE;
// Now the real build...
iFileAction := TCustomAction.Create( self ); // we want to put in same collection
iSubmenuItem := ActionManager1.AddAction( iFileAction, iSubMenuItem );
iSubmenuItem.Caption := 'Fred 1';
// etc
iFileAction := TCustomAction.Create( self ); // we want to put in same collection
iSubmenuItem := ActionManager1.AddAction( iFileAction, iSubMenuItem );
iSubmenuItem.Caption := 'Fred 2';
// etc
end;