Alain Alain - 1 month ago 8
C# Question

RibbonControl property callbacks (getPressed, getSupertip, etc.) never updating

While some office ribbon control properties can be set directly (such as the Label), most use a callbacks to set the property. For example a button's image:

<button id="btnRecalculate" getImage="GetRibbonControlImage" label="Recalculate Now" onAction="OnButtonAction" size="normal" />


The documentation is pretty clear on the syntax of these callbacks, but not on when and how frequently they are called upon.

I'm now faced with a problem where when a value is programatically changed, I want to modify one of the properties on the ribbon (for instance the tooltip on a button). I have a callback defined for the supertip like so:

<button id="btnSetServerURL" getSupertip="GetSuperTip" label="Set Server URL" />


And the code-behind:

public string GetSuperTip(IRibbonControl control)
{
switch( control.Id )
{
case "btnSetServerURL":
return "Click to set the server URL. (Currently: " + API.URL + ")";
default:
return "";
}
}


When that URL is changed, the next time the user mouses over that button, I expect the GetSuperTip callback to be invoked and the message to display the correct current URL, but right now the value is just being set the first time and never again.

Is there any way to get the behavior I seek? This is an Excel add-in, so as far as I know WPF style bindings aren't an option.

Answer

As you have discovered, Excel caches the state of ribbon controls. The only way to do what you want to do is to invalidate the ribbon/controls every time you have a state change that affects them. So in your case, whenever API.URL changes, you need to manually invalidate the ribbon or controls.

1) Include the onLoad attribute in your customUI XML.

<customUI ... onLoad="OnRibbonLoad" ...>
    ...
</customUI>

2) In your callback, store the ribbon interface:

private IRibbonUI _ribbon;

public void OnRibbonLoad(IRibbonUI ribbon)
{
    _ribbon = ribbon;
}

3) Later, when you have a state change that affects the ribbon, invalidate the ribbon or its controls:

    ...
    _ribbon.Invalidate();
    // or //
    _ribbon.InvalidateControl("YourControlID");
    ...