c# - 通过 Workbook_Open 事件更改 VSTO 选项卡的可见属性

标签 c# excel vsto

我已经为 Excel VSTO 项目编写了 Ribbon.xml 文件。选项卡元素如下所示:

<tab id="myId" idMso="TabAddIns" label="My Tab" visible="false">

当工作簿打开时,我希望选项卡默认隐藏,这是通过将 visible 属性设置为 false 来实现的。接下来,我想在 Workbook_Open 事件中将可见属性更改为 true。这就是我被困的地方。我不认为这会很难,但我花了几个小时在谷歌上搜索答案。似乎大多数示例 1) 通过 button callback 切换选项卡的可见性,这不是我想要做的,或者 2) 能够访问 ribbon's properties ,到目前为止我还无法复制(尽管这些资源中的大部分都是旧的,所以我认为 MS 从那时起就移动了这些属性)。

有谁知道如何轻松地将 visible 属性更改为 true 以便显示选项卡?

谢谢!

更新了更多信息:

ThisAddIn.cs

namespace Doodles_Reporting
{
    public partial class ThisAddIn
    {
        public RibbonApi ribbonApi;


        private void ThisAddIn_Startup(object sender, System.EventArgs e)
        {
        }

        private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
        {
        }

        protected override Microsoft.Office.Core.IRibbonExtensibility CreateRibbonExtensibilityObject()
        {
            return new Ribbon();
        }

        void Application_WorkbookOpen(Excel.Workbook Wb)
        {

            //first, check if there is an application/process for each workbook
            Excel.Workbooks books = Globals.ThisAddIn.Application.Workbooks;
            if (books.Count > 1)
            {
                try
                {
                    //close workbook that was just opened and then reopen it with new process/application.
                    string filePath = Wb.FullName;
                    Wb.Close();
                    Excel.Application excelApp = new Excel.Application();
                    excelApp.Visible = true;
                    excelApp.DisplayFullScreen = true;
                    excelApp.Workbooks.Open(filePath);
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK);
                }
            }
            else
            {
                //second, check if the workbook is a Doodles workbook
                try
                {
                    DocumentProperties props = (DocumentProperties)Wb.CustomDocumentProperties;
                    var selectedTable = props["selectedTable"].Value;
                    configureDoodles();
                }
                catch (Exception)
                {
                 //THIS IS WHERE I WANT TO SET THE RIBBON VISIBILITY TO FALSE
                }
            }   
        }

        private void configureDoodles()
        {
            RibbonApi.app = Globals.ThisAddIn.Application;
            RibbonApi.wBookPropertiesConfig = new WorkbookPropertiesConfig(RibbonApi.app.ActiveWorkbook);
            RibbonApi.presenter = new ExcelPresenter(RibbonApi.app.ActiveWorkbook);
            ribbonApi = new RibbonApi();
        }

        #region VSTO generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InternalStartup()
        {
            this.Startup += new System.EventHandler(ThisAddIn_Startup);
            this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
            this.Application.WorkbookOpen += new Excel.AppEvents_WorkbookOpenEventHandler(Application_WorkbookOpen);
        }

        #endregion
    }
}

丝带.cs

namespace Doodles_Reporting
{
    [ComVisible(true)]
    public class Ribbon : Office.IRibbonExtensibility
    {
        private Office.IRibbonUI ribbon;

        public Ribbon()
        {
        }

        #region IRibbonExtensibility Members

        public string GetCustomUI(string ribbonID)
        {
            return GetResourceText("Doodles_Reporting.Ribbon.xml");
        }

        #endregion

        #region Ribbon Callbacks
        //Create callback methods here. For more information about adding callback methods, visit http://go.microsoft.com/fwlink/?LinkID=271226

        public void Ribbon_Load(Office.IRibbonUI ribbonUI)
        {
            this.ribbon = ribbonUI;
        }

        public bool toggleVisibility(Office.IRibbonControl control)
        {
            return (control.Id == "TabAddIns") ? true : false;
        }

        public void onSomeEvent()
        {
            this.ribbon.InvalidateControl("TabAddIns");
        }

        public void SignIn(Office.IRibbonControl ribbonUI)
        {
            Globals.ThisAddIn.ribbonApi.signIn();
        }

        public void SqlCreatorFormLoad(Office.IRibbonControl ribbonUI)
        {
            Globals.ThisAddIn.ribbonApi.showSqlCreator();
        }

        public void refreshData(Office.IRibbonControl ribbonUI)
        {
            Globals.ThisAddIn.ribbonApi.refreshData();
        }

        public void drilldownSelectionLoad(Office.IRibbonControl ribbonUI)
        {
            Globals.ThisAddIn.ribbonApi.setDrilldownColumns();
        }

        public void Drilldown(Office.IRibbonControl ribbonUI)
        {
            Globals.ThisAddIn.ribbonApi.drilldown();
        }

        public void editProperties(Office.IRibbonControl ribbonUI)
        {

        }

        #endregion

        #region Helpers

        private static string GetResourceText(string resourceName)
        {
            Assembly asm = Assembly.GetExecutingAssembly();
            string[] resourceNames = asm.GetManifestResourceNames();
            for (int i = 0; i < resourceNames.Length; ++i)
            {
                if (string.Compare(resourceName, resourceNames[i], StringComparison.OrdinalIgnoreCase) == 0)
                {
                    using (StreamReader resourceReader = new StreamReader(asm.GetManifestResourceStream(resourceNames[i])))
                    {
                        if (resourceReader != null)
                        {
                            return resourceReader.ReadToEnd();
                        }
                    }
                }
            }
            return null;
        }

        #endregion
    }
}

最佳答案

丝带是一只有趣的野兽。它专门设计用于禁止您直接访问其任何元素并禁止您直接操作它们。相反,一切都是通过回调完成的。我没有太多使用 VSTO 的经验,但我可以解释你在没有 VSTO 的情况下用 C# 或 C++ 做什么,我相信你可以填补空白。

  1. 在您的功能区 XML 中设置一个 onLoad 回调。首次加载功能区时,Excel 将调用此方法(通过 IDispatch)。

    <customUI ... onLoad="OnRibbonLoaded">
    
  2. 实现您的 onLoad 回调,它应该存储所提供的 IRibbonUI 引用。

    public void OnRibbonLoaded(IRibbonUI ribbon)
    {
        this.ribbon = ribbon;
    }
    
  3. 对于要动态控制的属性,在功能区 XML 中定义回调。

    <tab ... getVisible="GetVisible">
    
  4. 实现可见性回调。如果功能区的多个部分使用相同的回调,则传入此方法的 IRibbonControl 实例可用于确定正在查询哪个选项卡/组/控件。

    public bool GetVisible(IRibbonControl control)
    {
        // here is where you should determine if your tab/group/control should be visible,
        return (some condition) ? true : false;
    }
    
  5. 每当您决定要更新可见性时,请使用 IRibbonUI 引用告诉 Excel 重新查询您的控件的属性(即调用您的回调)。

    void OnSomeEvent()
    {
        // you can tell Excel to update the entire ribbon
        this.ribbon.Invalidate();
    
        // or you can tell Excel to update a single tab/group/control
        this.ribbon.InvalidateControl("my_id");
    }
    

关于c# - 通过 Workbook_Open 事件更改 VSTO 选项卡的可见属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44789975/

相关文章:

c# - 添加后 ListObject 包含额外的标题

c# - Excel 插件 C# oracle 连接。安全吗?

c# - 需要解释事件处理和委托(delegate)

C# - 在 Silverlight 中访问 xap 内部的图像流

c# - 编码字符串数组的合适方法是什么?

c# - 表重新加载数据时滑动取消(UITableView、UITableViewCell、UITableViewDelegate)

excel - 根据条件从范围中选择单元格值

excel - 当多个单元格都为真时如何填充单元格

c# - 如何使用 Spreadsheet Gear C# 将 IRange 中所有日期格式的单元格转换为 DateTime?

c# - VSTO 将图像插入到 Outlook 中的 Word、Excel、PowerPoint 和邮件附件中