How do I disable Excel save button or override it's default functionality? I have a VSTO Excel project, and there is no need to save the Excel Workbook itself because we are using our own ways to save the document data using WCF. It even creates problems for us when user doesn't have writting rights: then he gets a "save as" dialog which still does nothing because I cancel the save event using following code:
void ThisWorkbook_BeforeSave(bool SaveAsUI, ref bool Cancel)
{
Cancel = true;
}
I can also cancel the "do you want to save" prompt using:
void ThisWorkbook_BeforeClose(ref bool Cancel)
{
this.Saved = true;
}
But if the file is read-only and I click the Save button, then I get a "this file is read-only" message. I don't want to get it.
If you are using Office 2010 or 2007 you could load a Ribbon that disables the built in commands save and save-as.
The most comprehensive documentation I know for the Ribbon markup is here:
MSDN Customise the Office Fluent Ribbon Interface - 1
MSDN Customise the Office Fluent Ribbon Interface - 2
MSDN Customise the Office Fluent Ribbon Interface - 3
I figured out that if you create a Template project instead of a Workbook project, then nothing happens when you click Save if my code from the question is applied.
Related
My goal is to simply offer my addin if Office application is launched with a certain argument.
Unfortunately, I could not find anything to help me do this. I have tried to use the Office Application Load Addin swtich /lc:Addin.dll with no success. One option I entertained was to create all of the Office addin registry entries upon time of wish to launch addin however this seemed extremely clumsy and way to much overhead. Also, the deal breaker for me was requiring registry creation elevated privileges in order to initialize the addin.
I decided to have my addin not do much of anything at startup unless a certain environment variable exists.
In order to do it this way I need to either set the ribbon to non-visible by default and show the Ribbon upon discovering the env variable. Or the opposite have the ribbon visible by default and hide the ribbon upon discovering env variable.
Things I have tried
Setting ribbon's tab Globals.Ribbons.MyRibbon.MyTab.visible = false.
Invalidating the Ribbon Globals.Ribbons.MyRibbon.RibbbonUi.Invalidate().
Invalidating the tab after setting visible to false Globals.Ribbons.MyRibbon.RibbbonUi.InvalidateControl(tabCtrlId).
The things tried dont include the dozens of thing to try to only load addin in certain circumstances.
I figured out a solution.
after digging into the base class AddinBase I discovered some methods available for me to override.
So I overrode the CreateRibbonExtensibilityObject method.
protected override IRibbonExtensibility CreateRibbonExtensibilityObject( )
{
if( Environment.GetCommandLineArgs( ).ToList( ).FirstOrDefault( a => a.ToLower( ).Contains( "/launchmyaddin" ) ) != null )
{
return null;
}
return base.CreateRibbonExtensibilityObject( );
}
What this does is prevent the ribbon from even being created if my switch is present and if it is present then I just pass off to the base class implementation in order to have the Addin create my ribbon like normal.
Also, CreateRibbonExtensibilityObject() returns an object that has a GetCustomUI( ribbonXml ) so we can create our custom ribbon from xml.
This gives us more power.
My solution only needed to show/hide a ribbon once only at startup. I did think about how this might be toggled on and off so I went poking around for other members I could override.
I believe you can override the CreateRibbonObjects( ) member which I think will get called upon every time the invalidate of a ribbon is called. Here you may be able to remove the item from the collection the base class returns that represents your ribbon you wish to hide.
If you use custom tab(s) (this is, ControlIdType=Custom) you may set visibility via:
foreach (var tab in Globals.Ribbons.Ribbon1.Tabs)
{
tab.Visible = false;
}
I am trying this to activate a custom tab:
Globals.Ribbons.MyRibbon.RibbonUI.ActivateTab("TabAddin")
It simply does nothing. No error, no tab activation, nothing.
If I change tab name to a non existing tab, it throws an exception, what it is obvious. That means the ActivateTab method is doing something, but not what it is intended to do.
Any help please? this is VSTO for Excel 2016.
It turned out that I was opening the book programmatically and immediately after calling Open method I was trying to activate the custom tab. At that stage, tab isn't created yet (maybe Open method is asychronous), that is why tab was not activated.
Finally I have used this to open the book:
var excelApp = Globals.ThisAddIn.Application;
excelApp.WorkbookActivate += excelApp_WorkbookActivate;
Excel.Workbook workbook = excelApp.Workbooks.Open(Filename: fileToOpen);
And in other part of the source file, I have:
void excelApp_WorkbookActivate(Excel.Workbook Wb)
{
Globals.ThisAddIn.Application.Wait(DateTime.Now.AddSeconds(1));
this.RibbonUI.ActivateTab("TabLeanAddin");
Globals.ThisAddIn.Application.WorkbookActivate -= excelApp_WorkbookActivate;
}
All the above caused the add-in to work as expected.
Cheers
Jaime
I'm developing an MFC Ribbon application on visual studio 2013 and I'm new in MFC developement.
I've added MFC Ribbon ComboBox from designer window. Now, I want to add data runtime into MFC Ribbon ComboBox, I've done google & read MSDN as well as Code Project example regarding MFC Ribbon. but, I was unable to figured how to get pointer to combobox and add data into it.
You can use CMFCRibbonBar::FindByID. So, something like this:
CMFCRibbonComboBox *pCombo = DYNAMIC_DOWNCAST(CMFCRibbonComboBox,
m_wndRibbonBar.FindByID(ID_COMBO1));
The ID you use (in the above example ID_COMBO1) is the ID you gave it in the Properties window in the ribbon designer, and m_wndRibbonBar is the member variable of the ribbon itself, which is usually auto-generated in your CMainFrm class.
i would like to know if it is possible to intercept the event generated by the Ribbon Button of an Excel Addin. I'm able to access to the .xlam source but seems there is no code in it that intercept that event, so I think the handler is in the compiled component. Is my assessment correct? And then, if yes, can I intercept a click on a button of the ribbon, maybe using an Application Level Handler?
Thank you,
DD
The Ribbon button has a callback assigned to its onAction attribute - it will be a Sub in the addin that has an iribboncontrol parameter (or similar). If you have can view the customui part of the add-in's XML you will be able to determine exactly which callback is relevant.
For programming Office Add-ins using C# 4.0, Microsoft provides two different ways of creating and/or modifying the Ribbon interface: you can use the Ribbon Designer or define the Ribbon's layout in Ribbon XML.
If you create a ribbon using the Ribbon designer, the class generated in the code behind has visibility to all the controls you've placed on the ribbon. So if I've placed a RibbonDropDown called "dropdown1", I could use the following code to add an item to it:
RibbonDropDownItem item = Factory.CreateRibbonDropDownItem();
item.Label = submatrix.Name;
item.Tag = submatrix;
this.dropDown1.Items.Add(item);
However, if you create the same Ribbon using Ribbon XML, dropDown1 or Factory aren't found ("The name does not exist in the current context").
Is there a way to access the items added to a Ribbon XML-defined ribbon in code?
Might be a little late, but hopefully this helps someone.
I was utterly confused about this same issue. Turns out, you can only access these controls as string ids, and the model is heavy on invalidation events. So for example, when you get a button click via onAction method, you only have the sender's id from the control object, however, in this event handler, you can invalidate the other controls and have their events called using
ribbon.InvalidateControl("MyCtl");
check out this MS Lab, it has everything you need to get up and running