I have a VSTO Addin ribbon that I made with XML, not the designer. It has a button on it that I only want to have enabled when the user is in a range that the addin controls.
I have the callback setup that works fine when the ribbon is loaded.
Ribbon1.cs
code
public bool refreshButtonState;
public void Ribbon_Load(Office.IRibbonUI ribbonUI)
{
this.ribbon = ribbonUI;
refreshButtonState = false;
ribbon.InvalidateControl("btnRefreshQuery");
}
public bool refreshEnabled(Office.IRibbonControl control)
{
return refreshButtonState;
}
I captured a worksheet change event to monitor the range the user is in below.
ThisAddIn.cs
code
void ThisWorkbook_SheetChange(object ws, Excel.Range rng)
{
//Disable Button state here.
if (rng.ListObject != null)
{
if (rng.ListObject.Name.StartsWith(LO_PREFIX))
{
//Enable Button state here.
}
}
}
I can't just pickup the ribbon from Globals.Ribbon.Ribbon1
as it has been suggested many times in the research I've done. Using the XML designer does not grant this functionality.
It seems like a lot of work to move my sheet listening functions over to the ribbon, to me they belong to the addin and not the ribbon anyway as they provide other functionality to the addin. I'm probably missing something obvious, but the documentation that exists is almost non existent. Other than piles of forum questions where the asker or the answerer does not get it.
TLDR: Change a property and invaldate a RibbonX control from code that is not part of the ribbon class.
I figured it out. Or at least a way to get there. I was thinking of parking a listener in the Ribbon class for an event in the Addin class.
I used this as a reference.
In my ThisAddin
class I created an event.
public delegate void UpdateRibbon(object source, StateChangeArgs e);
public event UpdateRibbon OnUpdateRibbon;
And the EventArgs class
public class StateChangeArgs : EventArgs
{
private bool EventInfo;
public StateChangeArgs(bool state)
{
EventInfo = state;
}
public bool GetInfo()
{
return EventInfo;
}
}
Added a listener and def to the Ribbon
Globals.ThisAddIn.OnUpdateRibbon +=new ThisAddIn.UpdateRibbon(ThisAddIn_OnUpdateRibbon);
And
public void ThisAddIn_OnUpdateRibbon(object a1, StateChangeArgs e)
{
refreshButtonState = e.GetInfo();
ribbon.InvalidateControl("btnRefreshQuery");
}
Then raised the event in the Addin
OnUpdateRibbon(this, new StateChangeArgs(true));
Works great /flex.