Developing for Microsoft Office with VSTO is fantastic, I mean, when the only other option is VBA. And that was basically the main reason I ended up working with VSTO in the first place.
A problem I had right in the beginning of my adventure was with the user interaction with the add-in. It was a simple custom toolbar with buttons, nothing fancy, but sometimes after using the add-in for a while the buttons would just randomly stop responding.
The bug was in the code that created the command bar and attached the event handlers. In order to configure and add the click event handler I was using a local variable to reference the newly added command bar button. Being local this variable would later be collected by the GC resulting in the loss of the event handler. So don’t forget… specify all command bar button variables at the add-in level to prevent them from being garbage collected.
You can check this behavior in the following example:
using System.Windows.Forms;
using Office = Microsoft.Office.Core;
public partial class ThisAddIn
{
private Office.CommandBar bar;
private Office.CommandBarButton showMsgCorrect;
private void ThisAddIn_Startup(object sender, EventArgs e)
{
bar = Application.CommandBars.Add(
"Example Bar",
Office.MsoBarPosition.msoBarTop,
false,
true);
// Do this
showMsgCorrect = (Office.CommandBarButton)bar.Controls.Add(
Office.MsoControlType.msoControlButton,
missing,
missing,
missing,
missing);
showMsgCorrect.Caption = "It Works";
showMsgCorrect.TooltipText = "Will always work";
showMsgCorrect.Style = Office.MsoButtonStyle.msoButtonCaption;
showMsgCorrect.Click += new Office._CommandBarButtonEvents_ClickEventHandler(button_Click);
// Don't do this - Garbage collection will break it
Office.CommandBarButton showMsgIncorrect;
showMsgIncorrect = (Office.CommandBarButton)bar.Controls.Add(
Office.MsoControlType.msoControlButton,
missing,
missing,
missing,
missing);
showMsgIncorrect.Caption = "Will Stop Working";
showMsgIncorrect.TooltipText = "Will stop working";
showMsgIncorrect.Style = Office.MsoButtonStyle.msoButtonCaption;
showMsgIncorrect.Click += new Office._CommandBarButtonEvents_ClickEventHandler(button_Click);
bar.Visible = true;
}
private void ThisAddIn_Shutdown(object sender, EventArgs e)
{
}
void button_Click(Office.CommandBarButton Ctrl, ref bool Cancel)
{
MessageBox.Show(
"Hello World!",
string.Empty,
MessageBoxButtons.OK,
MessageBoxIcon.Information);
GC.Collect();
}
#region VSTO generated code
private void InternalStartup()
{
this.Startup += new System.EventHandler(ThisAddIn_Startup);
this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
}
#endregion
}