经过上二篇的铺垫,现在终于可以加载菜单与工具栏了。先来看一下IService的接口实现里LoadCommand方法是如何来加载菜单与工具栏的:
![](/Images/OutliningIndicators/ContractedBlock.gif)
IService接口的实现
public class SignInRunner: IService
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
![](/Images/OutliningIndicators/InBlock.gif)
……
![](/Images/OutliningIndicators/InBlock.gif)
……
![](/Images/OutliningIndicators/InBlock.gif)
private MenuCfg menus;
![](/Images/OutliningIndicators/InBlock.gif)
private ToolBarCfg toolbars;
![](/Images/OutliningIndicators/InBlock.gif)
//……
![](/Images/OutliningIndicators/InBlock.gif)
//……
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
public SignInRunner ()
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/InBlock.gif)
//……
![](/Images/OutliningIndicators/InBlock.gif)
//……
![](/Images/OutliningIndicators/InBlock.gif)
string cfgPath = Assembly.GetExecutingAssembly().Location + ".config";
![](/Images/OutliningIndicators/InBlock.gif)
ConfigReader reader = new ConfigReader(cfgPath);
![](/Images/OutliningIndicators/InBlock.gif)
menus = reader.GetConfig("Menu") as MenuCfg;
![](/Images/OutliningIndicators/InBlock.gif)
toolbars = reader.GetConfig("ToolBar") as ToolBarCfg;
![](/Images/OutliningIndicators/InBlock.gif)
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ContractedSubBlock.gif)
IService 成员#region IService 成员
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
// ……
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
public void LoadCommand()
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/InBlock.gif)
try
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/InBlock.gif)
if (menus == null || menus.Items.Count == 0) return;
![](/Images/OutliningIndicators/InBlock.gif)
CommandMenu[] cmdMenu = CommandUtility.GetMenus(menus.Items,Context.OwnerPanel);
![](/Images/OutliningIndicators/InBlock.gif)
Context.OwnerMenu.MenuItems.AddRange(cmdMenu);
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
if (toolbars == null || toolbars.Items.Count == 0) return;
![](/Images/OutliningIndicators/InBlock.gif)
ToolBarButton sp = new ToolBarButton();
![](/Images/OutliningIndicators/InBlock.gif)
sp.Style = ToolBarButtonStyle.Separator;
![](/Images/OutliningIndicators/InBlock.gif)
Context.OwnerTool.Buttons.Add(sp);
![](/Images/OutliningIndicators/InBlock.gif)
Context.OwnerTool.Buttons.AddRange(CommandUtility.GetButtons(toolbars.Items,cmdMenu,Context.OwnerTool.ImageList));
![](/Images/OutliningIndicators/InBlock.gif)
}
![](/Images/OutliningIndicators/InBlock.gif)
catch(Exception e)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/InBlock.gif)
logNet.Error("加载[" + Name + "]的菜单与工具栏时出错--" + e.Message);
![](/Images/OutliningIndicators/InBlock.gif)
}
![](/Images/OutliningIndicators/InBlock.gif)
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
//……
![](/Images/OutliningIndicators/InBlock.gif)
//……
![](/Images/OutliningIndicators/InBlock.gif)
//……
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
#endregion
![](/Images/OutliningIndicators/InBlock.gif)
}
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
上述第一步先从模块的配置文件里读取到菜单与工具栏,得到相应的配置类;再把配置类转化为上二篇的带Command模式的菜单项(或工具栏按钮)类的数组;最后把数组加入到主窗体的菜单项集合(或工具栏按钮集合)中。
那如何把配置类转为菜单项(或工具栏按钮)类数组的呢?其实那个配置类本身也就是一个层层叠加的集合,每一项的属性跟菜单项(或工具栏按钮)的属性有对应,转化过程就是层层属性转化的过程,唯一另外要做的一件事就是把相应的单击事件附加上去。
具体过程见下面代码:
![](/Images/OutliningIndicators/ContractedBlock.gif)
从配置到菜单(工具栏)
![](/Images/OutliningIndicators/ExpandedBlockStart.gif)
public sealed class CommandUtility
{
![](/Images/OutliningIndicators/InBlock.gif)
private const string ICONPATH = "Icons";
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
private static EventHandler evh;
![](/Images/OutliningIndicators/InBlock.gif)
private static log4net.ILog logNet;
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
private static void CommandClick(object sender,System.EventArgs e)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/InBlock.gif)
ICommand cmd = (sender as ICommandHolder).GetCommand();
![](/Images/OutliningIndicators/InBlock.gif)
cmd.Execute();
![](/Images/OutliningIndicators/InBlock.gif)
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
static CommandUtility()
{
![](/Images/OutliningIndicators/InBlock.gif)
evh = new EventHandler(CommandClick);
![](/Images/OutliningIndicators/InBlock.gif)
logNet = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
![](/Images/OutliningIndicators/InBlock.gif)
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
![](/Images/OutliningIndicators/InBlock.gif)
/// 根据配置文件菜单列表得到实际菜单数组
![](/Images/OutliningIndicators/InBlock.gif)
/// </summary>
![](/Images/OutliningIndicators/InBlock.gif)
/// <param name="itemList"></param>
![](/Images/OutliningIndicators/InBlock.gif)
/// <param name="panel"></param>
![](/Images/OutliningIndicators/InBlock.gif)
/// <returns></returns>
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public static CommandMenu[] GetMenus(MenuItemList itemList,WeifenLuo.WinFormsUI.DockPanel panel)
{
![](/Images/OutliningIndicators/InBlock.gif)
int length = itemList.Count;
![](/Images/OutliningIndicators/InBlock.gif)
CommandMenu[] ret = new CommandMenu[length];
![](/Images/OutliningIndicators/InBlock.gif)
MenuItemCfg item;
![](/Images/OutliningIndicators/InBlock.gif)
ICommand command;
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
for (int i = 0;i < length;i++)
{
![](/Images/OutliningIndicators/InBlock.gif)
item = itemList[i];
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
if (item.Key != null && item.Key.Length > 0)
![](/Images/OutliningIndicators/InBlock.gif)
ret[i] = new CommandMenu(item.Caption + "(&" + item.Key + ")");
![](/Images/OutliningIndicators/InBlock.gif)
else
![](/Images/OutliningIndicators/InBlock.gif)
ret[i] = new CommandMenu(item.Caption);
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
ret[i].ID = item.ID;
![](/Images/OutliningIndicators/InBlock.gif)
ret[i].Enabled = !item.Disable;
![](/Images/OutliningIndicators/InBlock.gif)
if (item.Form != null && item.Form.Length > 0)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/InBlock.gif)
if (item.Method != null && item.Method.Length > 0)
![](/Images/OutliningIndicators/InBlock.gif)
command = new ExecuteCommand(item.ID,item.Form,panel.FindForm(),item.Method);
![](/Images/OutliningIndicators/InBlock.gif)
else
![](/Images/OutliningIndicators/InBlock.gif)
command = new ShowFormCommand(item.ID,item.Form,panel,item.IsModal);
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
ret[i].SetCommand(command);
![](/Images/OutliningIndicators/InBlock.gif)
ret[i].Click += evh;
![](/Images/OutliningIndicators/InBlock.gif)
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (item.Items.Count > 0)
{
![](/Images/OutliningIndicators/InBlock.gif)
ret[i].MenuItems.AddRange(GetMenus(item.Items,panel));
![](/Images/OutliningIndicators/InBlock.gif)
}
![](/Images/OutliningIndicators/InBlock.gif)
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
return ret;
![](/Images/OutliningIndicators/InBlock.gif)
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
![](/Images/OutliningIndicators/InBlock.gif)
/// 根据配置文件工具栏按钮列表得到实际按钮数组
![](/Images/OutliningIndicators/InBlock.gif)
/// </summary>
![](/Images/OutliningIndicators/InBlock.gif)
/// <param name="itemList"></param>
![](/Images/OutliningIndicators/InBlock.gif)
/// <param name="menus"></param>
![](/Images/OutliningIndicators/InBlock.gif)
/// <param name="imgList"></param>
![](/Images/OutliningIndicators/InBlock.gif)
/// <returns></returns>
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public static ToolBarButton[] GetButtons(TBarItemList itemList,CommandMenu[] menus,ImageList imgList)
{
![](/Images/OutliningIndicators/InBlock.gif)
int length = itemList.Count;
![](/Images/OutliningIndicators/InBlock.gif)
CommandToolBarButton[] ret = new CommandToolBarButton[length];
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
ToolBarItemCfg item;
![](/Images/OutliningIndicators/InBlock.gif)
ICommand cmd;
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
for (int i = 0;i < length;i++)
{
![](/Images/OutliningIndicators/InBlock.gif)
item = itemList[i];
![](/Images/OutliningIndicators/InBlock.gif)
ret[i] = new CommandToolBarButton(item.Caption);
![](/Images/OutliningIndicators/InBlock.gif)
ret[i].ID = item.ID;
![](/Images/OutliningIndicators/InBlock.gif)
if (item.Caption == "|")
![](/Images/OutliningIndicators/InBlock.gif)
ret[i].Style = ToolBarButtonStyle.Separator;
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
else
{
![](/Images/OutliningIndicators/InBlock.gif)
ret[i].Enabled = !item.Disable;
![](/Images/OutliningIndicators/InBlock.gif)
if (item.Image != null && item.Image.Length > 0)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/InBlock.gif)
imgList.Images.Add(new Icon(GetToolBarButtonIcon(item.Image)));
![](/Images/OutliningIndicators/InBlock.gif)
ret[i].ImageIndex = imgList.Images.Count - 1;
![](/Images/OutliningIndicators/InBlock.gif)
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
if (item.RelateMenuID != null && item.RelateMenuID.Length > 0)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/InBlock.gif)
cmd = getRelateMenu(item.RelateMenuID,menus);
![](/Images/OutliningIndicators/InBlock.gif)
if (cmd == null)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/InBlock.gif)
continue;
![](/Images/OutliningIndicators/InBlock.gif)
}
![](/Images/OutliningIndicators/InBlock.gif)
ret[i].SetCommand(cmd);
![](/Images/OutliningIndicators/InBlock.gif)
ret[i].OnClick += evh;
![](/Images/OutliningIndicators/InBlock.gif)
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (item.Items.Count > 0)
{
![](/Images/OutliningIndicators/InBlock.gif)
ret[i].Style = ToolBarButtonStyle.DropDownButton;
![](/Images/OutliningIndicators/InBlock.gif)
ContextMenu dpMenu = new ContextMenu();
![](/Images/OutliningIndicators/InBlock.gif)
dpMenu.MenuItems.AddRange(getContextMenu(item.Items,menus));
![](/Images/OutliningIndicators/InBlock.gif)
ret[i].DropDownMenu = dpMenu;
![](/Images/OutliningIndicators/InBlock.gif)
}
![](/Images/OutliningIndicators/InBlock.gif)
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
}
![](/Images/OutliningIndicators/InBlock.gif)
return ret;
![](/Images/OutliningIndicators/InBlock.gif)
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
![](/Images/OutliningIndicators/InBlock.gif)
/// 取得按钮的下拉菜单
![](/Images/OutliningIndicators/InBlock.gif)
/// </summary>
![](/Images/OutliningIndicators/InBlock.gif)
/// <param name="itemList"></param>
![](/Images/OutliningIndicators/InBlock.gif)
/// <param name="menus"></param>
![](/Images/OutliningIndicators/InBlock.gif)
/// <returns></returns>
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
private static CommandMenu[] getContextMenu(TBarItemList itemList,CommandMenu[] menus)
{
![](/Images/OutliningIndicators/InBlock.gif)
int length = itemList.Count;
![](/Images/OutliningIndicators/InBlock.gif)
CommandMenu[] ret = new CommandMenu[length];
![](/Images/OutliningIndicators/InBlock.gif)
ToolBarItemCfg item;
![](/Images/OutliningIndicators/InBlock.gif)
ICommand cmd;
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
for (int i = 0;i < length;i++)
{
![](/Images/OutliningIndicators/InBlock.gif)
item = itemList[i];
![](/Images/OutliningIndicators/InBlock.gif)
ret[i] = new CommandMenu(item.Caption);
![](/Images/OutliningIndicators/InBlock.gif)
ret[i].Enabled = !item.Disable;
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
if (item.RelateMenuID != null && item.RelateMenuID.Length > 0)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/InBlock.gif)
cmd = getRelateMenu(item.RelateMenuID,menus);
![](/Images/OutliningIndicators/InBlock.gif)
if (cmd == null)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/InBlock.gif)
continue;
![](/Images/OutliningIndicators/InBlock.gif)
}
![](/Images/OutliningIndicators/InBlock.gif)
ret[i].SetCommand(cmd);
![](/Images/OutliningIndicators/InBlock.gif)
ret[i].Click += evh;
![](/Images/OutliningIndicators/InBlock.gif)
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (item.Items.Count > 0)
{
![](/Images/OutliningIndicators/InBlock.gif)
ret[i].MenuItems.AddRange(getContextMenu(item.Items,menus));
![](/Images/OutliningIndicators/InBlock.gif)
}
![](/Images/OutliningIndicators/InBlock.gif)
}
![](/Images/OutliningIndicators/InBlock.gif)
return ret;
![](/Images/OutliningIndicators/InBlock.gif)
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
![](/Images/OutliningIndicators/InBlock.gif)
/// 取得工具栏按钮对应的菜单项的ICommand
![](/Images/OutliningIndicators/InBlock.gif)
/// </summary>
![](/Images/OutliningIndicators/InBlock.gif)
/// <param name="id">菜单ID</param>
![](/Images/OutliningIndicators/InBlock.gif)
/// <param name="menus">在其中查找菜单项</param>
![](/Images/OutliningIndicators/InBlock.gif)
/// <returns></returns>
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
private static ICommand getRelateMenu(string id,CommandMenu[] menus)
{
![](/Images/OutliningIndicators/InBlock.gif)
ICommand cmd;
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
for (int i = 0;i < menus.Length;i++)
{
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
if (menus[i].MenuItems.Count > 0)
{
![](/Images/OutliningIndicators/InBlock.gif)
CommandMenu[] children = new CommandMenu[menus[i].MenuItems.Count];
![](/Images/OutliningIndicators/InBlock.gif)
menus[i].MenuItems.CopyTo(children,0);
![](/Images/OutliningIndicators/InBlock.gif)
cmd = getRelateMenu(id,children);
![](/Images/OutliningIndicators/InBlock.gif)
if (cmd == null)
![](/Images/OutliningIndicators/InBlock.gif)
continue;
![](/Images/OutliningIndicators/InBlock.gif)
else
![](/Images/OutliningIndicators/InBlock.gif)
return cmd;
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
}else
{
![](/Images/OutliningIndicators/InBlock.gif)
cmd = menus[i].GetCommand();
![](/Images/OutliningIndicators/InBlock.gif)
if (cmd != null && id == cmd.ID)
![](/Images/OutliningIndicators/InBlock.gif)
return cmd;
![](/Images/OutliningIndicators/InBlock.gif)
}
![](/Images/OutliningIndicators/InBlock.gif)
}
![](/Images/OutliningIndicators/InBlock.gif)
return null;
![](/Images/OutliningIndicators/InBlock.gif)
}
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/InBlock.gif)
public static string GetToolBarButtonIcon(string fileName)
![](/Images/OutliningIndicators/InBlock.gif)
![](/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
![](/Images/OutliningIndicators/InBlock.gif)
return System.IO.Path.Combine(ICONPATH,fileName);
![](/Images/OutliningIndicators/InBlock.gif)
}
![](/Images/OutliningIndicators/InBlock.gif)
}
![](/Images/OutliningIndicators/None.gif)
![](/Images/OutliningIndicators/None.gif)
注意这里的设定,工具栏按钮(及其带的下拉菜单)肯定是要有相应的主菜单菜单项对应的,换言之就是不存在孤立的工具栏按钮,否则此按钮(及其带的下拉菜单)是无效的。
上面是模块的菜单与工具栏加载,主窗体的菜单与工具栏的加载当然与此类同,只是那里除此之外,还有一些固定的菜单与工具栏,比如“退出”、“帮助”、“关于”等等,无论需求如何变,这些东西总归是要的,我就直接在主程序的菜单与工具栏里把这些项的内容做死了,用不着经过配置。但顺序没有做死,比如“帮助”这样的菜单(或工具栏)总是加载到最后一项的。