产品文档 / Excel催化剂
第7波-VSTO开发中Ribbon动态加载菜单
在VS开发环境中,特别是VSTO的开发,微软已经现成地给开发者准备了设计器模式的功能区开发,相对传统的VBA、ExcelDna和其他方式的COM加载项开发来说,不需要手写xml功能区,直接类似拖拉窗体控件一样,即可完成Ribbon功能区的开发,开发效率极高。 这样的开发方式,非常适合于对Ribbon
在VS开发环境中,特别是VSTO的开发,微软已经现成地给开发者准备了设计器模式的功能区开发,相对传统的VBA、ExcelDna和其他方式的COM加载项开发来说,不需要手写xml功能区,直接类似拖拉窗体控件一样,即可完成Ribbon功能区的开发,开发效率极高。
这样的开发方式,非常适合于对Ribbon没有太高要求,太多的高级定制需要的场景,一般来说足够普通插件开发的需要,给用户在Ribbon功能区安放个按钮,让用户可以点击按钮即可触发某个功能运行。
有某些场景,想动态地加载菜单时,在设计器的功能区开发中,相对xml功能区,来得更容易,本篇给大家介绍两种场景。
具体场景
场景一、某些情况下才显示某个按钮
在Excel催化剂中,有一个【智能选区】的菜单,仅在用户选择数据区域,且仅选择一个单元格时,才会显示出来。


具体代码如下:
public void ExcelApp_SheetSelectionChangeGalSelectRangeVisibleOrNot(object Sh, Excel.Range Target)
{
try
{
if (Target.Cells.CountLarge == 1 && Target.CurrentRegion.Cells.CountLarge > 1)
{
Globals.Ribbons.Ribbon1.galSelectRange.Visible = true;//用强类型方式调用控件的Visible属性
}
else
{
Globals.Ribbons.Ribbon1.galSelectRange.Visible = false;
var panel = Utilities.TaskPanelUtility.GetCusTomTaskPaneByTitle(Utilities.TaskPanelUtility.SelectRangePanelTitle);
if (panel != null)
{
panel.Visible = false;
}
}
}
catch (Exception)
{
}
}
场景二、动态加载菜单项目数量
某些菜单下的内容不固定,根据用户的配置文件信息的条目数据多寡来动态加载,例如Excel催化剂中大量使用的动态菜单效果

需要使用动态菜单功能,需要在menu控制中,在设计器属性中打开Dynamic属性

在ItemsLoading事件中,用代码动态生成控件。

具体代码如下:
public void menuNumberFormatSetting_ItemsLoading(object sender, RibbonControlEventArgs e)
{
try
{
//打开任务窗格
Utilities.TaskPanelUtility.ShowOrTaskHidePanel(Utilities.TaskPanelUtility.NumberFormatPanelTitle,
Utilities.TaskPanelUtility.UscNumberFormat,
Utilities.TaskPanelUtility.CustomTaskPanesOfNumberFormat,
500,
true);
//动态生成菜单
RibbonMenu menu = sender as RibbonMenu;
menu.Items.Clear();
foreach (DataSet.AddinsDataSet.NumberFormatSettingRow row in Common.AddinsSettingDataset.NumberFormatSetting.Rows)
{
RibbonButton btn = Globals.Ribbons.Ribbon1.Factory.CreateRibbonButton();
btn.Name = "btnNumberFormat" + row.BtnIndex;
btn.Label = row.BtnLabel;
btn.Click += btnNumberFormat_Click;
menu.Items.Add(btn);
}
}
catch (Exception ex)
{
Common.OutMsgError(ex);
}
}
场景三、指定跳转至某功能区Tab选项卡
有时想让代码控制跳转到哪个功能区的TAB选项卡,例如本来代码运行完后,仍然想停留在插件的TAB选项卡上,供用户进行下一步按钮访问。
但因为上一步生成了图表或ListObject智能表之类的对象,功能区自动会智能跳转出这些对象相应的选项、设计等选项卡。插件的选项卡就失去焦点了。
使用以下代码激活TAB选项卡
Globals.Ribbons.Ribbon1.RibbonUI.ActivateTab("excelCatalyzer");

结语
使用VSTO开发,可以有现成的功能区设计器模式可利用,无需手工书写xml功能区,作大量的回调函数处理等,并且在动态显示、隐藏控件、动态添加菜单子项等操作都非常灵活方便,不失为VSTO开发的一大优势,虽然VSTO也有其弱点,但综合它带来的优势,笔者更喜欢使用VSTO来做开发。