返回Excel催化剂目录

产品文档 / 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来做开发。