Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Checkbox's OnAction does not do anything

Tags:

c#

excel

vsto

I have a custom ribbon with several checkboxes within a menu:

<?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>

This is the respective C# code:

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
    }
}

However, OnCheckboxChanged is never called. It works fine when I use this callback function with buttons but it does not with checkboxes, neither in the menu nor directly in the ribbon group. It also does work with getPressed instead of onAction.

like image 423
Michael Westwort Avatar asked Nov 07 '22 20:11

Michael Westwort


1 Answers

This thread and this Social MSDN thread both indicate onAction has a second argument in the parameter; isPressed.

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

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

It is also the way 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.");
    }
}

Defining Callback Methods

  1. It must be declared as public.
  2. Its name must match the name of a callback method that you assigned to a control in the Ribbon XML file.
  3. Its signature must match the signature of a type of callback method that is available for the associated Ribbon control.

Following on from that article I read Customizing the 2007 Office Fluent Ribbon for Developers (Part 3 of 3)

Can I have two callbacks with the same name but different signatures?

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.)

like image 100
Jeremy Thompson Avatar answered Nov 15 '22 06:11

Jeremy Thompson