启用和禁用加载项命令

如果外接程序中的某些功能应仅在某些上下文中可用,则可以以编程方式启用或禁用自定义外接程序命令。 例如,仅当光标位于表格中时,才启用用于更改表格标题的函数。

还可以指定在打开 Office 客户端应用程序时是启用或禁用命令。

注意

  • 本文假定你熟悉 外接程序命令的基本概念。 如果你最近未使用加载项命令(自定义菜单项和功能区按钮),请查看该文档。

  • 不支持以编程方式启用或禁用 上下文菜单 。 仅支持功能区按钮、菜单和选项卡。

Office 应用程序和平台支持

ExcelPowerPointWord 中提供了本文中所述的 API,作为 RibbonApi 1.1 要求集的一部分。 若要了解如何使用要求集测试平台支持,请参阅 Office 版本和要求集

需要共享运行时

本文中所述的 API 和清单标记要求加载项的清单指定它应使用 共享运行时。 有关详细信息,请参阅 配置外接程序以使用共享运行时

将默认状态设置为“已禁用”

默认情况下,Office 应用程序启动时会启用任何加载项命令。 如果要在 Office 应用程序启动时禁用自定义按钮或菜单项,请在清单中指定它。 该过程取决于外接程序使用的清单类型。

注意

Microsoft 365 的统一清单可用于生产 Outlook 加载项。它仅作为 Excel、PowerPoint 和 Word 加载项的预览版提供。

只需将具有 值的 false “enabled”属性添加到控件或菜单项对象即可。 下面显示了基本结构。

"extensions": [
    ...
    {
        ...
        "ribbons": [
            ...
            {
                ...
                "tabs": [
                    {
                        "id": "MyTab",
                        "groups": [
                            {
                                ...
                                "controls": [
                                    {
                                        "id": "Contoso.MyButton1",
                                        ...
                                        "enabled": false
                                    }
                                ]
                            }
                        ]
                    }
                ]
            }
        ]
    }
]

以编程方式更改状态

更改加载项命令的启用状态的基本步骤包括:

  1. 创建 一个 RibbonUpdaterData 对象,该对象 (1) 按清单中声明的 ID 指定命令及其父组和选项卡;和 (2) 指定命令的启用或禁用状态。
  2. RibbonUpdaterData 对象传递到 Office.ribbon.requestUpdate() 方法。

下面展示了一个非常简单的示例。 请注意,“MyButton”、“OfficeAddinTab1”和“CustomGroup111”是从清单复制的。

function enableButton() {
    Office.ribbon.requestUpdate({
        tabs: [
            {
                id: "OfficeAppTab1", 
                groups: [
                    {
                      id: "CustomGroup111",
                      controls: [
                        {
                            id: "MyButton", 
                            enabled: true
                        }
                      ]
                    }
                ]
            }
        ]
    });
}

我们还提供了几个接口(类型),使构建 RibbonUpdateData 对象变得更加容易。 下面是 TypeScript 中的等效示例,它利用了这些类型。

const enableButton = async () => {
    const button: Control = {id: "MyButton", enabled: true};
    const parentGroup: Group = {id: "CustomGroup111", controls: [button]};
    const parentTab: Tab = {id: "OfficeAddinTab1", groups: [parentGroup]};
    const ribbonUpdater: RibbonUpdaterData = { tabs: [parentTab]};
    Office.ribbon.requestUpdate(ribbonUpdater);
}

如果父函数是异步函数,则可以 await () 调用 requestUpdate ,但请注意,Office 应用程序控制何时更新功能区的状态。 requestUpdate() 方法会将更新请求加入队列中。 该方法将在请求排队后立即解析 promise 对象,而不是在功能区实际更新时解析。

更改状态以响应事件

一种应更改功能区状态的常见场景是用户启动的事件更改加载项上下文时。

考虑这样一种场景:当且仅当激活图表时,才应启用按钮。 第一步是将清单中按钮的 Enabled 元素设置为 false。 请参阅上面的示例。

第二步是分配处理程序。 这通常在 Office.onReady 函数中完成,如以下示例中所示,该函数将处理程序 (在后面的步骤) 创建的处理程序分配给工作表中所有图表的 onActivatedonDeactivated 事件。

Office.onReady(async () => {
    await Excel.run(context => {
        const charts = context.workbook.worksheets
            .getActiveWorksheet()
            .charts;
        charts.onActivated.add(enableChartFormat);
        charts.onDeactivated.add(disableChartFormat);
        return context.sync();
    });
});

第三步是定义 enableChartFormat 处理程序。 以下是一个简单示例,请参阅下面的最佳做法:测试控件状态错误,以获取更改控件状态的更可靠方法。

function enableChartFormat() {
    const button = {
        id: "ChartFormatButton", 
        enabled: true
    };
    const parentGroup = {
        id: "MyGroup",
        controls: [button]
    };
    const parentTab = {
        id: "CustomChartTab", 
        groups: [parentGroup]
    };
    const ribbonUpdater = {tabs: [parentTab]};
    Office.ribbon.requestUpdate(ribbonUpdater);
}

第四步是定义 disableChartFormat 处理程序。 除了将按钮对象的 enabled 属性设置为 false 之外,其他操作与 enableChartFormat 相同。

同时切换选项卡可见性和按钮的启用状态

requestUpdate 方法还用于切换自定义上下文选项卡的可见性。有关此代码和示例代码的详细信息,请参阅在 Office 外接程序中创建自定义上下文选项卡

最佳做法:测试控件状态错误

在某些情况下,调用 requestUpdate 后,功能区不会重画,因此控件的可单击状态不会发生更改。 因此,加载项的最佳做法是跟踪其控件的状态。 加载项应符合以下规则。

  1. 每当调用 requestUpdate 时,代码都应记录自定义按钮和菜单项的预期状态。
  2. 单击自定义控件时,处理程序中的第一个代码应检查该按钮是否应为可单击按钮。 如果不是,则该代码应报告或记录错误,然后再次尝试将按钮设置为预期状态。

以下示例显示用于禁用按钮和记录按钮状态的函数。 请注意,chartFormatButtonEnabled 是全局布尔变量,其初始化为与清单中按钮的 Enabled 元素相同的值。

function disableChartFormat() {
    const button = {
        id: "ChartFormatButton", 
        enabled: false
    };
    const parentGroup = {
        id: "MyGroup",
        controls: [button]
    };
    const parentTab = {
        id: "CustomChartTab", 
        groups: [parentGroup]
    };
    const ribbonUpdater = {tabs: [parentTab]};
    Office.ribbon.requestUpdate(ribbonUpdater);

    chartFormatButtonEnabled = false;
}

以下示例显示按钮的处理程序如何测试按钮的错误状态。 请注意,reportError 是用于显示或记录错误的函数。

function chartFormatButtonHandler() {
    if (chartFormatButtonEnabled) {

        // Do work here

    } else {
        // Report the error and try again to disable.
        reportError("That action is not possible at this time.");
        disableChartFormat();
    }
}

错误处理

在某些情况下,Office 无法更新功能区,并将返回错误。 例如,如果升级了加载项,并且升级后的加载项具有一组不同的自定义加载项命令,则必须关闭并重新打开 Office 应用程序。 在此之前,requestUpdate 方法将返回错误 HostRestartNeeded。 以下是如何处理此错误的示例。 在此示例中,reportError 方法向用户显示错误。

function disableChartFormat() {
    try {
        const button = {
            id: "ChartFormatButton", 
            enabled: false
        };
        const parentGroup = {
            id: "MyGroup",
            controls: [button]
        };
        const parentTab = {
            id: "CustomChartTab", 
            groups: [parentGroup]
        };
        const ribbonUpdater = {tabs: [parentTab]};
        Office.ribbon.requestUpdate(ribbonUpdater);

        chartFormatButtonEnabled = false;
    }
    catch(error) {
        if (error.code == "HostRestartNeeded"){
            reportError("Contoso Awesome Add-in has been upgraded. Please save your work, close the Office application, and restart it.");
        }
    }
}