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

2023-12-26

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

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

打开工作簿时,我希望默认情况下隐藏该选项卡,这是通过将visible 属性设置为 false 来实现的。接下来,我想在 Workbook_Open 事件中将visible属性更改为true。这就是我被困住的地方。我不认为这会很难,但我花了几个小时在谷歌上搜索答案。似乎大多数示例 1)通过,这不是我想要做的,或者2)能够访问丝带的属性 https://stackoverflow.com/questions/6399111/vsto-enable-ribbon-button-only-when-a-document-is-loaded,到目前为止我还无法复制(尽管这些资源大部分都是旧的,所以我认为微软从那时起就移动了这些属性)。

有谁知道如何轻松地将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. Set an onLoad功能区 XML 中的回调。 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. 每当您决定要更新可见性时,请告诉 Excel 使用以下命令重新查询控件的属性(即调用回调):IRibbonUI参考。

    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");
    }
    
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

通过 Workbook_Open 事件更改 VSTO 选项卡的可见属性 的相关文章

  • 如何创建可以像 UserControl 一样编辑的 TabPage 子类?

    我想创建一个包含一些控件的 TabPage 子类 并且我想通过设计器来控制这些控件的布局和属性 但是 如果我在设计器中打开子类 我将无法像在 UserControl 上那样定位它们 我不想创建一个带有 UserControl 实例的 Tab
  • C++:重写已弃用的虚拟方法时出现弃用警告

    我有一个纯虚拟类 它有一个纯虚拟方法 应该是const 但不幸的是不是 该接口位于库中 并且该类由单独项目中的其他几个类继承 我正在尝试使用这个方法const不会破坏兼容性 至少在一段时间内 但我找不到在非常量方法重载时产生警告的方法 以下
  • Clang 编译器 (x86):80 位长双精度

    我正在尝试在 x86 Windows 平台上使用本机 80 位长双精度 海湾合作委员会选项 mlong double 80 https gcc gnu org onlinedocs gcc x86 Options html似乎不适用于 cl
  • 构造函数中显式关键字的使用

    我试图了解 C 中显式关键字的用法 并查看了这个问题C 中的explicit关键字是什么意思 https stackoverflow com questions 121162 但是 那里列出的示例 实际上是前两个答案 对于用法并不是很清楚
  • 访问者和模板化虚拟方法

    在一个典型的实现中Visitor模式 该类必须考虑基类的所有变体 后代 在许多情况下 访问者中的相同方法内容应用于不同的方法 在这种情况下 模板化的虚拟方法是理想的选择 但目前这是不允许的 那么 模板化方法可以用来解析父类的虚方法吗 鉴于
  • 如何从 C# 控制器重定向到外部 url

    我使用 C 控制器作为网络服务 在其中我想将用户重定向到外部网址 我该怎么做 Tried System Web HttpContext Current Response Redirect 但没有成功 使用控制器的重定向 http msdn
  • IronPython:没有名为 json 的模块

    我安装了 IronPython 我的 python 文件如下所示 import sys print sys version import json 运行它的代码 var p Python CreateEngine var scope p C
  • VBA Excel:将范围值分配给新范围

    我在将一个工作簿范围中的值分配给当前工作簿中的某个范围时遇到问题 当我使用 Range A1 C1 分配我的范围时 此代码工作正常 但是当我使用 Range Cells 1 1 Cells 1 3 定义我的范围时 该函数会失败 Sub Co
  • 如何从网站下载 .EXE 文件?

    我正在编写一个应用程序 需要从网站下载 exe 文件 我正在使用 Visual Studio Express 2008 我正在使用以下代码 private void button1 Click object sender EventArgs
  • 无法将类型“System.IO.Stream”隐式转换为“Java.IO.InputStream”

    我提到了一些类似的问题 但没有一个涉及IO 当我使用时 我在java中使用了相同的代码Eclipse 那次就成功了 但现在我尝试在中使用这段代码Mono for Android C 它不起作用 我正在尝试运行此代码来创建一个InputStr
  • C# 中条件编译符号的编译时检查(参见示例)?

    在 C C 中你可以这样做 define IN USE 1 define NOT IN USE 1 define USING system 1 system 1 IN USE 进而 define MY SYSTEM IN USE if US
  • 获取 2 个数据集 c# 中的差异

    我正在编写一个简短的算法 它必须比较两个数据集 以便可以进一步处理两者之间的差异 我尝试通过合并这两个数据集并将结果更改放入新的数据集来实现此目标 我的方法如下所示 private DataSet ComputateDiff DataSet
  • 尚未处理时调用 Form 的 Invoke 时出现 ObjectDisposeException

    我们得到一个ObjectDisposedException从一个电话到Invoke在尚未处理的表格上 这是一些演示该问题的示例代码 public partial class Form2 Form void Form2 Load object
  • 在类的所有方法之前运行一个方法

    在 C 3 或 4 中可以做到这一点吗 也许有一些反思 class Magic RunBeforeAll public void BaseMethod runs BaseMethod before being executed public
  • 如何修复日期过滤器 VBA,因为它没有拾取我范围内的所有日期

    我正在尝试创建一个过滤器来过滤掉我选择的日期内的所有日期 我选择的日期将始终反映整个月 例如 如果我需要 2019 年 5 月的数据 我将输入开始日期为 01 05 2019 结束日期为 31 05 2019 我的数据过滤器将需要选取经过我
  • 我在在线程序挑战编译器中遇到演示错误

    include
  • 双精度类型二维多维数组的 pinvoke 编组作为 c# 和 c++ 之间的输入和输出

    我有以下我正在尝试解决的双物质类型的 2d 多维数组的 c 和 c pinvoke 编组 我已经查看了以下热门内容以获得我目前拥有的内容使用双精度数组进行 P Invoke 在 C 和 C 之间编组数据 https stackoverflo
  • 如何使用 php 将 *.xlsb 转换为数组或 *.csv

    我正在尝试转换 xlsb文件到php array or csv文件 或至少 xls 我尝试使用PHPExcel 但看起来它无法识别该文件中的内容 我注意到 你可以重命名 xlsb文件到 zip文件 然后使用命令行解压缩unzip zip 之
  • Googletest:如何异步运行测试?

    考虑到一个包含数千个测试的大型项目 其中一些测试需要几分钟才能完成 如果按顺序执行 整套测试需要一个多小时才能完成 通过并行执行测试可以减少测试时间 据我所知 没有办法直接从 googletest mock 做到这一点 就像 async选项
  • 使用 Crypto++ 获取 ECDSA 签名

    我必须使用 Crypto 在变量中获取 ECDSA 签名 我在启动 SignMessage 后尝试获取它 但签名为空 我怎样才能得到它 你看过 Crypto wiki 吗 上面有很多东西椭圆曲线数字签名算法 http www cryptop

随机推荐