Custom tab in Excel Ribbon cannot be activated - excel

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

Related

Excel AddIn Issue on Workbooks.Open() being stuck on Excel Home Screen

Previously this code for opening and activating(bringing workbook to front) has worked for other builds of Microsoft office, however Microsoft's latest build(16.0.11126.20234) seemed to create a problem with opening an existing excel workbook.
testWorkbook = this.Application.Workbooks.Open(path);
testWorkbook.Activate();
The issue is when launching excel and using an 'Open' method on a workbook:
Excel application launches
The title of on the top of the window changes to the workbook name you are trying to open, however the main body of the window is still the default Excel Home screen( home, options, recent workbooks, templates)
Selecting options or any other item on the splash screen results in the splash screen closing and displays the workbook that was intended to be open
I've tried removing any existing code, and created a new AddIn solution with just the code Microsoft documentation provides for loading and displaying a workbook.
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
Workbook testWorkbook;
string path = "C:\\Path\\To\\Workbook\\TestingBookOpen.xlsx";
try
{
testWorkbook = this.Application.Workbooks.Open(path);
testWorkbook.Activate();
}
catch (Exception ex){
string message = ex.Message;
}
}
I know there are workarounds including:
You can disable the start screen from excel directly.
You can click into options and then exit it which will bring the sheet up
You can have excel already open and it'll work fine
But I'm looking for a programmatic solution/workaround for when my AddIn launches, and to see whether other's have come across the same problem in Microsoft Office's latest build.

Show or Hide a VSTO Addin Ribbon

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

How to open a hyperlink in separate browser tab in Coded UI

I have three different Hyperlinks on a web page
Planning.
Solutions.
Contact Us.
I want to open them in separate browser tab one by one using codedUI.
i have written the above code to obtain the list of Hyperlink
HtmlControl Hyperlink = new HtmlControl(browser);
Hyperlink.SearchProperties.Add(HtmlControl.PropertyNames.ControlType,"Hyperlink");
UITestControlCollection controls = Hyperlink.FindMatchingControls();
foreach(UITestControl control in controls)
{
if (control is HtmlHyperlink)
{
HtmlHyperlink link = (HtmlHyperlink)control;
if(link.InnerText=="Planning"|| link.InnerText== "Solutions")
{
//separate Tab logic goes here
}
}
}
I need the help related to opening a hyperlink in new browser tab. Is it possible in CodedUI ?
By default if you click the mouse middle button (or click the scroll wheel), it opens a link in new tab. I would modify your code as below in this case,
if(link.InnerText=="Planning"|| link.InnerText== "Solutions")
{
//Open Link in New tab, by clicking middle button
Mouse.Click(link, MouseButtons.Middle);
}
You can do this a couple different ways. I would use #Prageeth-Saravan 's approach first to see if it works because it's easier and actually tests your UI. You could also:
Get the URL from the found link control
Send the "New tab" keyboard shortcut
Reinstantiate your browser window object to be sure it's pointing to the new tab
Navigate to that URL
The reason why I bolded step 3 is regardless of approach, if you intend to assert or interact with anything in a new tab you're going to have to remember that the CodedUI software will still be "Looking" at the old tab until you reinitialize it.

Excel Custom Task Pane not showing

I'm showing a custom task pane in an excel VSTO add-in, I'm building it and showing it as thus:
var ctrl = new CellTaskPane();
var pane = CustomTaskPanes.Add(ctrl, "Custom Sheet");
pane.DockPosition = Office.MsoCTPDockPosition.msoCTPDockPositionRight;
pane.DockPositionRestrict = Office.MsoCTPDockPositionRestrict.msoCTPDockPositionRestrictNoChange;
pane.Visible = true;
This is being done in the ThisAddin.cs file and it working just fine on my machine, both under a Debug session and with the add-in installed via the click-once installer.
However, installing the add-in on a colleague's machine is proving troublesome.
The add-in is functioning and the context menu / ribbon is working perfectly, but the pane just refuses to show.
I have a toggle button on the ribbon which toggles the Visible property on the pane and even clicking that isn't forcing the pane to show.
Any help on this would be greatly appreciated, Google is proving useless for this.
Thanks.
I should mention that CellTaskPane is just a UserControl as per the docs on MSDN: http://msdn.microsoft.com/en-us/library/aa942846.aspx
Turns out it wasn't anything we were doing directly!
There was another add-in installed (third party) which for some bizarre reason was interfering with the pane being shown (no idea why or how).
Shame that Excel doesn't show any sort of error or at least throw an exception.
Ah well.
I suggest you try a very, very simple custom task pane first to see if this works. I put together the most simple example I could think of, basically a single text box that gets a value pushed into it and this is returned to the ribbon when a button is pushed.
If you were to try this then I would do it as a new solution. Create a new VSTO project with a "Designer mode" ribbon. Add a toggle button and a normal button below it. Then copy in this code:
ThisAddIn.cs
using System;
using Office = Microsoft.Office.Core;
namespace ExcelAddIn1
{
public partial class ThisAddIn
{
private Microsoft.Office.Tools.CustomTaskPane pane;
private CellTaskPane ctrl = new CellTaskPane();
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
pane = CustomTaskPanes.Add(ctrl, "Custom Sheet");
pane.DockPosition = Office.MsoCTPDockPosition.msoCTPDockPositionRight;
pane.DockPositionRestrict = Office.MsoCTPDockPositionRestrict.msoCTPDockPositionRestrictNoChange;
pane.Visible = true;
pane.VisibleChanged += new EventHandler(taskPaneValue_VisibleChanged);
ctrl.SetName("test");
}
private void taskPaneValue_VisibleChanged(object sender, System.EventArgs e)
{
Globals.Ribbons.Ribbon1.toggleButton1.Checked = pane.Visible;
}
public Microsoft.Office.Tools.CustomTaskPane TaskPane
{
get
{
return pane;
}
}
public CellTaskPane MyContainer
{
get
{
return ctrl;
}
}
private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
{
}
#region VSTO generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InternalStartup()
{
this.Startup += new System.EventHandler(ThisAddIn_Startup);
this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
}
#endregion
}
}
Add a new class called CellTaskPane.cs:
using System;
using System.Windows.Forms;
using System.Drawing;
using System.ComponentModel;
namespace ExcelAddIn1
{
public class CellTaskPane : System.Windows.Forms.UserControl
{
public System.Windows.Forms.TextBox test;
public CellTaskPane()
{
InitializeComponent();
}
public void InitializeComponent()
{
test = new System.Windows.Forms.TextBox();
test.Location = new System.Drawing.Point(120, 8);
test.Size = new System.Drawing.Size(232, 20);
test.TabIndex = 0;
Controls.AddRange(new System.Windows.Forms.Control[] { test });
Size = new System.Drawing.Size(375, 150);
}
public void SetName(string text)
{
test.Text = text;
}
public string GetName()
{
return test.Text;
}
}
}
Add the following code to Ribbon1.cs:
using System;
using Microsoft.Office.Tools.Ribbon;
namespace ExcelAddIn1
{
public partial class Ribbon1
{
private void toggleButton1_Click(object sender, RibbonControlEventArgs e)
{
Globals.ThisAddIn.TaskPane.Visible = ((RibbonToggleButton)sender).Checked;
}
private void button1_Click(object sender, RibbonControlEventArgs e)
{
button1.Label = Globals.ThisAddIn.MyContainer.GetName();
}
}
}
Obviously you will need to do a little tweaking to get this to work, I tried to take the default names for a new project and the buttons.
When you run this you should get a custom task pane. When you switch to the "TabAddIn" and click the toggle button it should show/ hide the task pane. When you click the normal button the contents of the only field in the task pane should be copied as the button name. I defaulted this to "test", so even if the task pane isn't visible you can see if it is in memory or not?
I tested this and it appears to work fine. Basically this is just a hacked up version of the examples on MSDN. If you wanted you could probably do this yourself anyway? If nothing else this will enable you to see if there is anything in the more complex ribbon you are working on that causes issues... or if this is a fundamental problem with your colleague's machine.
I had the same problem, but it was not any addin I could disable (COM+ or Excel).
I had my excel configured to open files at startup
(Excel Options -> Advanced -> General)
There, I had an .XLAM that customized the ribbon.
When I cleared this configuration, my addin started working.
I ran into exactly this problem while trying to get the Microsoft sample code for "Walkthrough: Synchronizing a Custom Task Pane with a Ribbon Button" working. Here's a link to the page:
http://msdn.microsoft.com/en-us/library/bb608590.aspx
After starting from scratch about three times and scouring the Internet for a clue as to what I might have been doing wrong, I came across this question and Clint's answer that an add-in was causing his problem. I had a few add-ins enabled, but with some trial and error I found the culprit: Microsoft's own "Analysis Toolpack"!
Once I disabled Analysis Toolpack, the custom pane started appearing and disappearing as expected.
So, as Clint discovered, the first thing you should probably try if you run into this issue is to disable all add-ins and see if that does the trick. If so, then you can go back and begin turning them on until you find the one that is interfering with your custom pane visibility.
Well, after following #GaryP's advice, disabling my other add-ins, and thinking that I'd solved the problem (albeit without access to my other add-ins), I discovered that the add-in would disappear whenever I opened more than one workbook.
But at that point, I didn't just get a missing taskpane or a silent fail, I actually got an error:
The taskpane has been deleted or is otherwise no longer valid
So it seems that disabling add-ins isn't solving the problem in itself, but rather disabling add-ins is reducing the number of open workbooks (even if add-ins aren't visible, they can still have a Ribbon handle)...
The underlying cause is the use of SDI in 2013 and later.
So, now I can have all of my add-ins loaded.
Create a new instance of the task pane for each workbook. Make the following changes to your code and the task pane works even with addins enabled.
private void Application_WorkbookActivate(Microsoft.Office.Interop.Excel.Workbook wb)
{
pane = CustomTaskPanes.Add(ctrl, "Custom Sheet");
pane.DockPosition = Office.MsoCTPDockPosition.msoCTPDockPositionRight;
pane.DockPositionRestrict = Office.MsoCTPDockPositionRestrict.msoCTPDockPositionRestrictNoChange;
pane.Visible = true;
pane.VisibleChanged += new EventHandler(taskPaneValue_VisibleChanged);
ctrl.SetName("test");
}
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
this.Application.WorkbookActivate += new Excel.AppEvents_WorkbookActivateEventHandler(
Application_WorkbookActivate);
}
If you find that even after closing all other add-ins, the TaskPane still doesn't show, it may be because it is loaded in your "Personal.xlsb" workbook. After closing it, I tried making the pane visible again and I received an error that it had been closed.
I had the same problem and didn't fix it by disableing the analysis toolpack, but, rather i had to move the XLAM out of its installed folder (Break the reference to it, since you couldn't remove it through Excel) and it started working.
I've sense added the files back and it continues to work. Activating the addin does cause my custom taskbar to break. Not sure what this long term fix is here.
I know this is very old, but it can be useful for anyone who may look up for an answer, but here we go:
if you are adding the new taskpane under ThisAddIn_Startup, it will only add it once at the start of the excel, and it will not be present for any other Excel session, so based on the following link that shows how to handle multiple sessions:
https://learn.microsoft.com/en-us/previous-versions/office/developer/office-2007/bb264456(v=office.12)?redirectedfrom=MSDN#Anchor_2
I came up with the conclusion that I should create a new taskpane under the other events that can fire when I needed the taskpane, then validate if the current window has the taskpane or not, and create a new one if not and show it. the event can be any trigger like ribbon button, open document, etc.
Dim CurrentTaskPane As Microsoft.Office.Tools.CustomTaskPane = Nothing
Globals.ThisAddIn.RemoveOrphanedTaskPanes() 'to remove any unused taskpane
For Each ctp As Microsoft.Office.Tools.CustomTaskPane In Globals.ThisAddIn.CustomTaskPanes
If ctp.Window.Hwnd = Excel.Application.ActiveWindow.Hwnd Then
CurrentTaskPane = ctp
Exit For
End If
Next
If CurrentTaskPane Is Nothing Then
CurrentTaskPane = Globals.ThisAddIn.CustomTaskPanes.Add(New ControlName, "My TaskPane", Excel.Application.ActiveWindow)
End If
CurrentTaskPane.Visible = True
You can find the 'RemoveOrphanedTaskPanes' code from the link provided.
Summarizing other answers: It appears that this is due to loading other Add-ins, .XLAM files, etc. These can be loaded from many different places, and you need to check them all, and remove them. You may be able to reenable them later, so back everything up. Here is a checklist:
File -> Options -> Advanced -> General -> "At startup, open all files in..." Remove those files and disable the option.
File -> Options -> Add-ins -> Check all the Active application add-ins. Near the bottom of the dialog, use the Mange: Excel/Com Add-ins to view the Add-ins and disable or remove them. Even the Microsoft included ones could be causing it, so disable them as well. They do not allow you to remove them, which is fine, as long as they are disabled.
C:\Users\$USERNAME\AppData\Roaming\Microsoft\Excel\XLSTART Remove all files from this directory.
C:\Users\$USERNAME\AppData\Roaming\Microsoft\AddIns Remove all files from this directory.
After this, try again to load the Add-In. Then, add back the things you need one by one and keep testing. They may break it again, or not, there does not appear to be consensus on what kind of Add-In does and does not break the task pane.
If anyone discovers more places to look for Add-Ins, I will add them to the list.

disable Excel save button

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.

Resources