Load excel Ribbon on demand - c#

I would like to add functionality to my Excel addin so I could load different Ribbons on demand.
At the moment I am trying by exporting the ribbon to XML and loading it
private Microsoft.Office.Core.IRibbonExtensibility ribbonObj;
protected override Microsoft.Office.Core.IRibbonExtensibility CreateRibbonExtensibilityObject()
{
DialogResult RibbonToLoad = MessageBox.Show("Yes = V2 No = V3", "Select Version", MessageBoxButtons.YesNo);
switch (RibbonToLoad)
{
case DialogResult.Yes:
ribbonObj = new RibbonV2();
return ribbonObj;
case DialogResult.No:
ribbonObj = new RibbonV3();
return ribbonObj;
}
return new RibbonV2();
}
The problema with this is I cannot find how to switch this Ribbon. I don't find it inside the Globals. object.
Also I tried without exporting to XML, but also I couldn't achieve the load on demand of a different ribbon while running(e.g. clicking a button on a WPF window...)
Any idea how to get this? I would like to have the possibility of loading different ribbons on the same addin(but only one would be present at once)

You can't manage the process of loading ribbon controls. But you can change visibility of your controls at runtime. The IRibbonUI interface provides the Invalidate and InvalidateControl methods that allow to trigger your callbacks where you can change visibility at runtime (getVisible).
In the following example, starting the host application triggers the onLoad event procedure that then calls a procedure which creates an object representing the Ribbon UI. Next, a callback procedure is defined that invalidates all of the controls on the UI and then refreshes the UI.
The following is the XML markup for Office to load the custom ribbon:
<customUI … onLoad=”MyAddInInitialize” …>
The following is the callback method for the onLoad event:
Dim MyRibbon As IRibbonUI
Sub MyAddInInitialize(Ribbon As IRibbonUI)
Set MyRibbon = Ribbon
End Sub
Sub myFunction()
‘ Invalidates the caches of all of this add-in’s controls
MyRibbon.Invalidate()
End Sub
You can read more about the Ribbon UI in the following series of articles in MSDN:
Customizing the 2007 Office Fluent Ribbon for Developers (Part 1 of 3)
Customizing the 2007 Office Fluent Ribbon for Developers (Part 2 of 3)
Customizing the 2007 Office Fluent Ribbon for Developers (Part 3 of 3)

Related

UI Ribbon: How to unpress a toggle button?

There are 4 toggle buttons, when I be click on one, the other 3 are not clicked
For example, when I click public, Confidential's Click will be removed. Only 1 can be selected.
<toggleButton id="textButtonpublic" getLabel="getpublic" getImage="getcolor" onAction="PublicAction" getVisible="getvisiblepublic" getPressed="GetPressedPublic" />
public void PublicAction(IRibbonControl control, bool pressed){
GetPressedConfidential();}
public bool GetPressedConfidential(IRibbonControl control)
{
return false;
}
It didn't work when I called the GetPressedConfidential method.
If the ribbon button comes from your add-in you need to use the Invalidate or InvalidateControl methods of the IRibbonUI interface that allows invalidating the cached value for a single control or all controls on the Ribbon user interface.
For example, if an add-in writer implements the getImage callback procedure for a button, the function is called once, the image loads, and then if the image needs to be updated, the cached image is used instead of recalling the procedure. This process remains in place for the control until the add-in signals that the cached values are invalid by using the InvalidateControl method, at which time, the callback procedure is again called and the return response is cached.
The getPressed callback has the following signature for the toggelButton control:
C#: bool GetPressed(IRibbonControl control)
VBA: Sub GetPressed(control As IRibbonControl, ByRef returnValue)
C++: HRESULT GetPressed([in] IRibbonControl *pControl, [out, retval] VARIANT_BOOL *pvarfPressed)
Visual Basic: Function GetPressed(control As IRibbonControl) As Boolean
The Fluent UI (aka Ribbon UI) is described in depth in the following articles:
Customizing the 2007 Office Fluent Ribbon for Developers (Part 1 of 3)
Customizing the 2007 Office Fluent Ribbon for Developers (Part 2 of 3)
Customizing the 2007 Office Fluent Ribbon for Developers (Part 3 of 3)

Adding to Ribbon at run time works once

Hi I'm trying to add the current open contacts phone numbers to a ribbon.
I have created the ribbon and added a SplitButton which will contain the phone numbers.
In 'ThisAddin' when the current explorer changes it triggers an event which simply gets the item type. If its a contact it calls
//ThisAddin.cs on explorer change event - if is contact run:
Globals.Ribbons.CallContact.AddButton(contactItem.BusinessTelephoneNumber);
//Ribbon class
internal void AddButton(string name)
{
if (name != null && name.Count() > 2)
{
RibbonButton item = Globals.Factory.GetRibbonFactory().CreateRibbonButton();
item.Label = name;
item.ShowLabel = true;
this.newSplit.Items.Add(item);
}
}
This works once, first time opening a contact the phone number is displayed in the ribbon. Opening another contact window will cause the ribbon items to be added but are blank and null.
I'm simply trying to add the contacts phone numbers to the ribbon and leave them there while the user can open another contact and the same code runs adding the phone numbers to the ribbon.
I don't need to keep reference to the items once they are added. Thank you for the help. I feel there needs to be an invoke in here somewhere.
You must tell Outlook to refresh the ribbon. See https://learn.microsoft.com/en-us/visualstudio/vsto/walkthrough-updating-the-controls-on-a-ribbon-at-run-time?view=vs-2019 for the sample code.
You will need to specify a callback to retrieve the button's caption instead of hard-coding it in the ribbon's XML.
Note that since you can have multiple inspectors open, you must provide data specific to each item opened in its own inspector.
The Ribbon UI is a static thing because it is loaded once at startup (or before the window is shown). The best what you can do is to define callbacks and get them called wherever you need. For example, you can define 'getVisible' callback for your ribbon controls instead of adding new elements at runtime.
The IRibbonUI.Invalidate method invalidates the cached values for all of the controls of the Ribbon user interface.
You can customize the Ribbon UI by using callback procedures in COM add-ins. For each of the callbacks that the add-in implements, the responses are cached.
For example, if an add-in writer implements the getImage callback procedure for a button, the function is called once, the image loads, and then if the image needs to be updated, the cached image is used instead of recalling the procedure. This process remains in place until the add-in signals that the cached values are invalid by using the Invalidate method, at which time, the callback procedure is again called and the return response is cached. The add-in can then force an immediate update of the UI by calling the Refresh method.
<customUI … OnLoad="MyAddinInitialize" …>
Dim MyRibbon As IRibbonUI
Sub MyAddInInitialize(Ribbon As IRibbonUI)
Set MyRibbon = Ribbon
End Sub
Sub myFunction()
MyRibbon.Invalidate() ' Invalidates the caches of all of this add-in's controls
End Sub
The Fluent UI is described in-depth in the following articles:
Customizing the 2007 Office Fluent Ribbon for Developers (Part 1 of 3)
Customizing the 2007 Office Fluent Ribbon for Developers (Part 2 of 3)
Customizing the 2007 Office Fluent Ribbon for Developers (Part 3 of 3)
Also, you may find the Walkthrough: Create a custom tab by using Ribbon XML helpful. Note, you can export an existing custom ribbon UI to the XML and continue dealing with a raw markup.

Can I hide an icon on a Ribbon for particular users?

I want to show an icon on a Ribbon tab for particular users.
like...
If username ="Mike"
hide icon1
else
show icon1
Is there any way to get username who are using Excel workbook in C#?
I can set up password for this icon but if I can get username, it will be easier.
You can get the username from the WindowsIdentity:
if (System.Security.Principal.WindowsIdentity.GetCurrent().Name.Equals("username"))
{
button1.Visible = true;
}
else
{
button1.Visible = false;
}
The Application class from the Excel object model provides the UserName property. Moreover, you can't set the Visible property directly for Ribbon UI controls. You need to use callbacks (getVisible) and call the IRibbonUI.Invalidete or InvalidateControl methods to get your callbacks invoked. You can read more about the Ribbon UI in the following series of articles in MSDN:
Customizing the 2007 Office Fluent Ribbon for Developers (Part 1 of 3)
Customizing the 2007 Office Fluent Ribbon for Developers (Part 2 of 3)
Customizing the 2007 Office Fluent Ribbon for Developers (Part 3 of 3)

Updating an Outlook ribbon label from another form (VSTO)

I feel completely dumb for not being able to figure this out, because I know I am missing something easy. Anyway, I have a settings form that opens when a user clicks the settings button on the Outlook ribbon I have created for my Outlook add-in. In the settings form is a checkbox, and when the user checks the box, I need to change the text of a label located back on the ribbon.
I am used to WPF, so normally what I would do in this situation is invoke a dispatcher since the form is on a different thread, but the whole dispatcher thing seems to go completely out the window with VSTO. What am I missing? Solutions for Windows Forms don't seem to work either.
Here is an example of what I am trying to do. This code would be in my settings form that pops up.
private void statusCheckBox_CheckedChange(object sender, eventargs e)
{
OutlookRibbon outlookRibbon = new outlookRibbon();
If(statusCheckBox.checked)
{
outlookRibbon.statusLabel.Label = "Checkbox Checked";
}
}
I know in the example I am creating a new instance of my ribbon, so that is why I am not seeing the label update, but I don't really know where to go from here. Any help is appreciated.
Ribbon is a static thing from its birth. You can't set properties in the direct way. Instead, you need to use callbacks for updating controls. When you need to update the state of your controls you need to call the Invalidate or InvalidateControl methods of the IRibbonUI interface to force the host application call your callbacks to grab new values. For example:
In the XML markup file:
<customUI … OnLoad=”MyAddInInitialize” …>
In the code:
Dim MyRibbon As IRibbonUI
Sub MyAddInInitialize(Ribbon As IRibbonUI)
Set MyRibbon = Ribbon
End Sub
Sub myFunction()
MyRibbon.Invalidate() ‘ Invalidates the caches of all of this add-in’s controls
End Sub

c# Excel - Display ribbon on exit

I'm using VSTO to design an application with an Excel interface. I want to hide the ribbon on startup (shouldn't be needed in the application) and re-display it on exit (if the user had it originally displayed), to avoid irritating people who use the application and want a ribbon the next time they open Excel.
I can hide the ribbon using essentially the following code in ThisWorkbook_Startup (from this question Excel 2007 Minimize the Ribbon programatically but Not the menu bar):
Office.CommandBars cbs = null;
cbs = Application.CommandBars;
foreach (Office.CommandBar commandBar in cbs)
{
if (commandBar.Name == "Ribbon")
{
this.Application.ActiveWindow.Activate();
Application.SendKeys("^{F1}", true);
}
}
However, the same code or similar variations from the previously referenced question do not seem to work when placed in either the ThisWorkbook_Shutdown or ThisWorkbook_BeforeClose methods. The code is hit but never seems to execute - the ribbon is never restored.
Is there another way to restore the ribbon on exit?
Thanks,
Andrew

Categories