上下文菜单按钮在Excel加载项中触发一次

时间:2016-05-23 13:55:13

标签: c# excel vsto

我的上下文菜单按钮只触发一次。 btn对象在启动时死亡。我该如何解决?

如何尽早修复调用对象?

public partial class ThisAddIn
{
    private void ThisAddIn_Startup(object sender, System.EventArgs e)
    {                        
        PicPaste btn = new PicPaste(this.Application);}
class PicPaste
{
    private Excel.Application application;
    private Office.CommandBarButton   picpasteMenuItem;
    public PicPaste(Excel.Application app)
    {
        application = app;
        CreatePicpasteBtn();
    }

    public  void CreatePicpasteBtn()
    {
        Office.MsoControlType contextMenuItem = Office.MsoControlType.msoControlButton;
        Office.CommandBar commandBarCell = application.CommandBars["Cell"];
        picpasteMenuItem = commandBarCell.Controls.Add(contextMenuItem, Type.Missing, Type.Missing, 5, true) 
            as Office.CommandBarButton;

        if (picpasteMenuItem != null)
        {
            picpasteMenuItem.Style = Office.MsoButtonStyle.msoButtonCaption;
            picpasteMenuItem.Caption = "Вставить изображение в коммент";
            picpasteMenuItem.Click += new Office._CommandBarButtonEvents_ClickEventHandler(
                PicPasteMenuItemClick);
        }
    }

    private static void PicPasteMenuItemClick(Office.CommandBarButton Ctrl, ref bool CancelDefault)
    {
       ...some code here

    }
}

2 个答案:

答案 0 :(得分:0)

问题是您在方法/事件中声明并实例化对象PicPaste btn = new PicPaste(this.Application);。这意味着它将适用于此程序;当程序结束时,它会超出范围,最终会被垃圾收集。

您需要在类级别之外声明任何在加载项的生命周期内存在的对象 - 在任何过程之外。然后他们将保持在范围内,直到您的加载项被卸载。

所以,例如:

public partial class ThisAddIn
{
  PicPaste btn = null;
  private void ThisAddIn_Startup(object sender, System.EventArgs e)
  {                        
    btn = new PicPaste(this.Application);
  }

答案 1 :(得分:0)

看起来PicPaste实例的范围有限。但是这种方法是正确的 - 保持在类级别定义的源对象,以防止它被GC从堆中滑动。尝试使用将存储在加载项类级别的控件列表,或类似的东西:

PicPaste btn = null;
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{                        
    btn = new PicPaste(this.Application);
}