Checkbox 的 OnAction 不做任何事情

Checkbox's OnAction does not do anything

我有一个自定义功能区,菜单中有多个复选框:

<?xml version="1.0" encoding="UTF-8"?>
<customUI xmlns="http://schemas.microsoft.com/office/2006/01/customui" onLoad="Ribbon_Load">
  <ribbon>
    <tabs>
      <tab id="ribbon" label="Ribbon">
        <group id="ribbonGroup" label="Group">
          <menu id="menu" label="Menu">
            <checkBox id="checkbox1" label="Checkbox 1" visible="true" onAction="OnCheckboxChanged"/>            
            <checkBox id="checkbox2" label="Checkbox 2" visible="true" onAction="OnCheckboxChanged"/>            
            <checkBox id="checkbox2" label="Checkbox 2" visible="true" onAction="OnCheckboxChanged"/>            
        </group>
      </tab>
    </tabs>
  </ribbon>
</customUI>

这是相应的 C# 代码:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Drawing;
using System.Windows.Forms;
using Office = Microsoft.Office.Core;
using Excel = Microsoft.Office.Interop.Excel;
using Microsoft.Office.Tools.Excel;

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

        public SSRRibbon()
        {
        }

        #region IRibbonExtensibility-Member
        public string GetCustomUI(string ribbonID)
        {
            return GetResourceText("ExcelAddIn1.SSRRibbon.xml");
        }
        #endregion

        #region ribbon callback functions
        public void Ribbon_Load(Office.IRibbonUI ribbonUI)
        {
            this.ribbon = ribbonUI;
        }

        public void OnCheckboxChanged(Office.IRibbonControl control)
        {
            int i = 1;
        }
        #endregion

        #region auxiliary
        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
    }
}

然而,OnCheckboxChanged 从未被调用。当我将此回调函数与按钮一起使用时它工作正常但它不适用于复选框,既不在菜单中也不直接在功能区组中。它也适用于 getPressed 而不是 onAction

这个thread and this Social MSDN thread都说明onAction参数中有第二个参数; isPressed.

public void markAsRead_OnAction(Office.IRibbonControl control, bool isPressed)
{

public void cbViewAction(Office.IRibbonControl control, bool pressed)
{

也是这样 official documentation states to do it:

public void OnActionCallback(Office.IRibbonControl control, bool isPressed)
{
    if (control.Id == "checkBox1")
    {
        MessageBox.Show("You clicked " + control.Id);
    }
    else
    {
        MessageBox.Show("You clicked a different control.");
    }
}

定义回调方法

  1. 必须声明为public。
  2. 它的名称必须与您在功能区 XML 文件中分配给控件的回调方法的名称相匹配。
  3. 其签名必须与可用于相关功能区控件的回调方法类型的签名相匹配。

根据那篇文章,我阅读了 Customizing the 2007 Office Fluent Ribbon for Developers (Part 3 of 3)

我可以有两个同名但不同签名的回调吗?

Although you can do this, we recommended that you have different callbacks for each control (and not count on built-in overloading to handle the distinction between the two callbacks). For example, assume that you write a Fluent UI add-in with two callbacks of the same name, as in the following code.

public void doSomething(IRibbonControl control, bool pressState);
public void doSomething(IRibbonControl control);

Also assume that your XML markup defines a toggleButton control and a button control, and that each of them has an onAction="doSomething" callback. In this instance, only the toggleButton control will work, because of the Visual Basic and Visual C# auto-generated IDispatch implementation. If you write a C++ add-in and implement IDispatch yourself, this case will work. (In other words, it is best not to do this.)