上下文菜单按钮在 Excel 加载项中触发一次
context-menu button fires once in Excel Add-In
我的上下文菜单按钮只触发一次。
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
}
}
问题是您在 method/event 中声明和实例化对象 PicPaste btn = new PicPaste(this.Application);
。这意味着它将适用于此程序;当程序完成时它超出范围,最终将被垃圾收集。
您需要在 class 级别[=20] 声明 在您的加载项的生命周期内应该存在的任何对象=] - 在任何程序之外。然后它们将保留在范围内,直到您的加载项被卸载。
因此,例如:
public partial class ThisAddIn
{
PicPaste btn = null;
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
btn = new PicPaste(this.Application);
}
看起来 PicPaste
实例的范围受到某种限制。但该方法是正确的——将源对象定义在 class 级别,以防止它被 GC 从堆中清除。尝试使用将存储在加载项 class 级别或类似内容的控件列表:
PicPaste btn = null;
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
btn = new PicPaste(this.Application);
}
我的上下文菜单按钮只触发一次。 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
}
}
问题是您在 method/event 中声明和实例化对象 PicPaste btn = new PicPaste(this.Application);
。这意味着它将适用于此程序;当程序完成时它超出范围,最终将被垃圾收集。
您需要在 class 级别[=20] 声明 在您的加载项的生命周期内应该存在的任何对象=] - 在任何程序之外。然后它们将保留在范围内,直到您的加载项被卸载。
因此,例如:
public partial class ThisAddIn
{
PicPaste btn = null;
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
btn = new PicPaste(this.Application);
}
看起来 PicPaste
实例的范围受到某种限制。但该方法是正确的——将源对象定义在 class 级别,以防止它被 GC 从堆中清除。尝试使用将存储在加载项 class 级别或类似内容的控件列表:
PicPaste btn = null;
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
btn = new PicPaste(this.Application);
}