功能区 XML:重用 UI 元素以保持代码“干燥”

Ribbon XML: Reusing UI Elements to Keep Code `DRY`

我发现自己在编写 RibbonXML UI 时重复了很多 XML。

以下面的contextMenu为例

<contextMenu idMso="ContextMenuObjectsGroup">
    <!-- Lots of XML describing the items -->
</contextMenu>

现在,我也希望相同的项目出现在 ContextMenuShape 菜单中,所以我发现自己重复了上面的内容:

<contextMenu idMso="ContextMenuShape">
    <!-- Lots of XML describing the items -->
</contextMenu>

所有包含的控件都需要新的 Ids - 并且背后的代码需要调整以响应这些新控件这一事实加剧了这种情况。

问题:

Is there a way to de-duplicate this code and simply reference control groups (which are implemented once) from within, e.g., contextMenus, ribbons and so on?

编辑 1:更多用例

我开发了几个可应用于形状、表格、图表等的自定义用户函数。我目前将这些工具包含在选项卡集中 TabSetDrawingTools。但是,我还需要将它们包含在表格和图表的相应选项卡中。

目前看来,只有两个选择:

  1. 如上所述,完全复制并粘贴所有代码 - 这与任何最佳实践背道而驰

  2. 以某种方式实现我的 "own" 功能区 XML 标签。然后,我阅读自己的 XML,查找诸如 <customControlGroup id="myId" /> 之类的标签,然后从中以编程方式生成最终的功能区 XML 并将其传递给 Office。也就是说,要实现看似如此简单的事情,这听起来很麻烦。

编辑 2:不支持使用 <control />

Ribbon XML 提供 <control /> 标签,允许您 duplicate/clone 内置控件。但是,根据 documentation(并尝试过),它不适用于自定义控件和控件组(例如,通过引用它们的 ididQ)。

虽然我不是 VSTO 专家,但我已经大量使用 Ribbon XML,而且我认为你想要完成的事情无法通过 Ribbon XML 完成。但根据您的其中一条评论,我认为您可能遗漏了拼图的一部分,这将使这更容易。

使用普通回调和tag

您的代码应该适应选择,而不是控件(无论如何您都需要这样做以进行错误检查),并且您可以在多个控件中使用相同的回调。如果需要进一步区分,也可以使用tag属性。只有 id 会有所不同,但可以忽略它,您的代码每次都可以表现相同。

<contextMenu idMso="ContextMenuObjectsGroup">
    <control id="mycustomcontrol1" onAction="PerformChange" tag="type1" ?>
</contextMenu>
<contextMenu idMso="ContextMenuShape">
    <control id="mycustomcontrol2" onAction="PerformChange" tag="type2" ?>
</contextMenu>

public void PerformChange(IRibbonControl control)
{
    bool type1 = controlTag == "Type1";
    bool type2 = controlTag == "Type2";        

    if (/* selection contains appropriate content */)
    {
        // perform changes, checking the tag as needed
    }

}

使用 XSLT

这主要是对上一节的补充,以避免必须手动 copy/paste 每组控件。

大多数人不需要经常编写或编辑功能区 XML。您通常只做一次,然后偶尔进行更改。如果您真的经常需要 write/edit 功能区 XML,您可以维护功能区 XML 的基本副本,其中包含空的 <contextMenu>,并且当您进行更改时, 运行 一个转换,它将你的元素的副本放入每个相关的 <contextMenu>,具有唯一的 id(也就是说,再次,否则被忽略)。

我个人发现这些事情很难做到恰到好处,除非你经常这样做。如果您对 XSLT 不是很熟悉,或者不经常(每天?每周?)更改您的功能区,我怀疑任何时间都不会通过使用它来收回。