更改加载项命令的可用性

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

注意

支持的功能

可针对以下功能以编程方式更改外接程序命令的可用性。

  • 功能区按钮、菜单和选项卡。
  • 上下文菜单项。

Office 应用程序和要求集支持

下表概述了支持配置外接程序命令可用性的 Office 应用程序。 它还列出了使用 API 所需的要求集。

外接程序命令功能 要求集 受支持的 Office 应用程序
功能区按钮、菜单和选项卡 RibbonApi 1.1
  • Excel
  • PowerPoint
  • Word
上下文菜单项 ContextMenuApi 1.1
  • Excel
  • PowerPoint
  • Word

提示

若要了解如何使用要求集测试平台支持,请参阅 Office 版本和要求集

配置共享运行时

若要更改功能区或上下文菜单控件或项的可用性,必须先将外接程序的清单配置为使用 共享运行时。 有关如何设置共享运行时的指南,请参阅 将 Office 外接程序配置为使用共享运行时

以编程方式更改外接程序命令的可用性

启动时停用功能区控件

注意

在 Office 应用程序启动时,只能停用功能区上的控件。 无法在启动时停用添加到上下文菜单的自定义控件。

默认情况下,当 Office 应用程序启动时,功能区上的自定义按钮或菜单项可供使用。 若要在 Office 启动时停用它,必须在清单中指定此项。 该过程取决于外接程序使用的清单类型。

Microsoft 365 的统一清单

注意

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

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

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

仅加载项清单

只需在紧接下方添加 Enabled 元素, (不在控件项的 Action 元素) 。 然后,将其值设置为 false

下面显示了配置 Enabled> 元素的<清单的基本结构。

<OfficeApp ...>
  ...
  <VersionOverrides ...>
    ...
    <Hosts>
      <Host ...>
        ...
        <DesktopFormFactor>
          <ExtensionPoint ...>
            <CustomTab ...>
              ...
              <Group ...>
                ...
                <Control ... id="Contoso.MyButton3">
                  ...
                  <Action ...>
                  <Enabled>false</Enabled>
...
</OfficeApp>

更改功能区控件的可用性

若要更新功能区上按钮或菜单项的可用性,请执行以下步骤。

  1. 创建 一个 RibbonUpdaterData 对象,该对象指定以下内容:
    • 命令的 ID,包括其父组和选项卡。ID 必须与清单中声明的 ID 匹配。
    • 命令的可用性状态。
  2. RibbonUpdaterData 对象传递到 Office.ribbon.requestUpdate() 方法。

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

function enableButton() {
    const ribbonUpdaterData = {
        tabs: [
            {
                id: "OfficeAppTab1",
                groups: [
                    {
                      id: "CustomGroup111",
                      controls: [
                        {
                            id: "MyButton",
                            enabled: true
                        }
                      ]
                    }
                ]
            }
        ]
    };

    Office.ribbon.requestUpdate(ribbonUpdaterData);
}

有几个接口 (类型) ,以便更轻松地构造 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 对象,而不是在功能区实际更新时解析。

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

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

更改状态以响应事件

功能区或上下文菜单控件的状态应更改的常见方案是用户发起的事件更改加载项上下文。 请考虑这样一种场景:按钮在激活图表时且仅在激活时才可用。 尽管以下示例使用功能区控件,但类似的实现可以应用于上下文菜单上的自定义项。

  1. 首先,将清单中按钮的 Enabled> 元素设置为 。<false 有关如何配置此功能的指南,请参阅 启动时停用功能区控件

  2. 然后,分配处理程序。 这通常在 Office.onReady 函数中完成,如以下示例所示。 在此示例中, (在后面的步骤中创建的处理程序) 分配给 Excel 工作表中所有图表的 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();
        });
    });
    
  3. 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);
    }
    
  4. disableChartFormat定义处理程序。 它与 处理程序相同 enableChartFormat ,只不过按钮对象的 enabled 属性设置为 false

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

在某些情况下,功能区或上下文菜单在调用 后 requestUpdate 不会重新绘制,因此控件的可单击状态不会更改。 因此,加载项最好跟踪其控件的状态。 加载项应符合以下规则。

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

以下示例演示了一个函数,该函数停用功能区上的按钮并记录该按钮的状态。 在此示例中, 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 to make the button unavailable again.
        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.");
        }
    }
}

另请参阅