C# Excel DNA加载项在以下情况下卸载;是否要保存“提示”;选择“取消”按钮
当我按File->Exit(或Alt+F4)或X时,我会收到“是否保存更改”对话框的提示,在该对话框中我可以选择“取消”。因此Excel可以继续,但我的Excel dna外接程序再也不会收到通知,并保持卸载状态C# Excel DNA加载项在以下情况下卸载;是否要保存“提示”;选择“取消”按钮,c#,html,excel,wpf,excel-dna,C#,Html,Excel,Wpf,Excel Dna,当我按File->Exit(或Alt+F4)或X时,我会收到“是否保存更改”对话框的提示,在该对话框中我可以选择“取消”。因此Excel可以继续,但我的Excel dna外接程序再也不会收到通知,并保持卸载状态 提前谢谢各位 据我所知,在用户单击“取消”之前执行WorkbookBeforeClose时会出现问题。还有一些选择 简单的方法是,您可以在WorkbookBeforeClose事件中保存活动的woorkbook(woorkbook对象具有save和saveas方法)。由于工作簿已保
提前谢谢各位 据我所知,在用户单击“取消”之前执行WorkbookBeforeClose时会出现问题。还有一些选择 简单的方法是,您可以在WorkbookBeforeClose事件中保存活动的woorkbook(woorkbook对象具有save和saveas方法)。由于工作簿已保存,因此不会显示“保存”对话框,用户也不会单击“取消”按钮 另一种解决方案是在WorkbookBeforeClose中调用自定义保存对话框。我在其他项目中使用了以下代码。关闭前的工作簿可能如下所示:
private void ActiveWorkbook_BeforeClose(ref bool Cancel)
{
DefaultSaveExcel(Excel.ActiveWorkbook,ref Cancel);
if (!Cancel)
{
//if enters here is because the workbook is actually closing
Delete(Excel.ActiveWorkbook.Name);
}
}
public void DefaultSaveExcel(Workbook wb, ref bool Cancel)
{
while (wb.Saved == false && Cancel == false)
{
var result = ShowMessageDialogSave();
if (result == System.Windows.Forms.DialogResult.Yes)
{
var sa = CreateExcelSaveDialog(wb.FullName);
if (sa.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
wb.SaveAs(sa.FileName);
wb.Save();
}
}
else if (result == System.Windows.Forms.DialogResult.No)
{
wb.Saved = true;
}
else if (result == System.Windows.Forms.DialogResult.Cancel)
{
Cancel = true;
}
}
}
public System.Windows.Forms.SaveFileDialog CreateExcelSaveDialog(string name = null)
{
var sa = new System.Windows.Forms.SaveFileDialog();
sa.Filter = "Excel files (*.xlsx)|*.xlsx";
if (!string.IsNullOrEmpty(name))
sa.FileName = name;
sa.CreatePrompt = true;
return sa;
}
public DialogResult ShowMessageDialogSave()
{
var app = (Microsoft.Office.Interop.Excel.Application)ExcelDna.Integration.ExcelDnaUtil.Application;
NativeWindow xlMain = new NativeWindow();
xlMain.AssignHandle(new IntPtr(app.Hwnd));
var message = "Do you want to save pending changes?";
if (Thread.CurrentThread.CurrentCulture.TwoLetterISOLanguageName.ToLower() == "es")
message = "¿Desea guardar los cambios pendientes?";
return System.Windows.Forms.MessageBox.Show(xlMain, message, "Microsoft Excel", System.Windows.Forms.MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning,MessageBoxDefaultButton.Button1);
}
public override void OnBeginShutdown(ref Array custom)
{
base.OnBeginShutdown(ref custom);
//I PUT MY CUSTOM CODE HERE:
CloseAllPanes();
ExcelTaskExecutor.Destroy();
}
实际的DefaultSaveExcel实现可能如下所示:
private void ActiveWorkbook_BeforeClose(ref bool Cancel)
{
DefaultSaveExcel(Excel.ActiveWorkbook,ref Cancel);
if (!Cancel)
{
//if enters here is because the workbook is actually closing
Delete(Excel.ActiveWorkbook.Name);
}
}
public void DefaultSaveExcel(Workbook wb, ref bool Cancel)
{
while (wb.Saved == false && Cancel == false)
{
var result = ShowMessageDialogSave();
if (result == System.Windows.Forms.DialogResult.Yes)
{
var sa = CreateExcelSaveDialog(wb.FullName);
if (sa.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
wb.SaveAs(sa.FileName);
wb.Save();
}
}
else if (result == System.Windows.Forms.DialogResult.No)
{
wb.Saved = true;
}
else if (result == System.Windows.Forms.DialogResult.Cancel)
{
Cancel = true;
}
}
}
public System.Windows.Forms.SaveFileDialog CreateExcelSaveDialog(string name = null)
{
var sa = new System.Windows.Forms.SaveFileDialog();
sa.Filter = "Excel files (*.xlsx)|*.xlsx";
if (!string.IsNullOrEmpty(name))
sa.FileName = name;
sa.CreatePrompt = true;
return sa;
}
public DialogResult ShowMessageDialogSave()
{
var app = (Microsoft.Office.Interop.Excel.Application)ExcelDna.Integration.ExcelDnaUtil.Application;
NativeWindow xlMain = new NativeWindow();
xlMain.AssignHandle(new IntPtr(app.Hwnd));
var message = "Do you want to save pending changes?";
if (Thread.CurrentThread.CurrentCulture.TwoLetterISOLanguageName.ToLower() == "es")
message = "¿Desea guardar los cambios pendientes?";
return System.Windows.Forms.MessageBox.Show(xlMain, message, "Microsoft Excel", System.Windows.Forms.MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning,MessageBoxDefaultButton.Button1);
}
public override void OnBeginShutdown(ref Array custom)
{
base.OnBeginShutdown(ref custom);
//I PUT MY CUSTOM CODE HERE:
CloseAllPanes();
ExcelTaskExecutor.Destroy();
}
希望这有帮助,
阿曼多阿曼多!非常感谢你的帮助 我发现有一个IDTExtensibility2接口,它承载加载项发生的事件通知,例如加载、卸载、更新等等。因此,我将该接口用于命名空间ExcelDna中的ExcelComAddIn类。集成:
public class ExcelComAddIn : IDTExtensibility2
{
public ExcelComAddIn();
protected string ProgId { get; }
public virtual void OnAddInsUpdate(ref Array custom);
public virtual void OnBeginShutdown(ref Array custom);
public virtual void OnConnection(object Application, ext_ConnectMode ConnectMode, object AddInInst, ref Array custom);
public virtual void OnDisconnection(ext_DisconnectMode RemoveMode, ref Array custom);
public virtual void OnStartupComplete(ref Array custom);
}
我注意到onBeginShutton()方法在对话框提示后运行!这就是我想要的,所以我去掉了WorkbookBeforeClose事件,重写了onBeginShutton()方法,并将WorkbookBeforeClose事件中的代码放入onBeginShutton()中,如下所示:
private void ActiveWorkbook_BeforeClose(ref bool Cancel)
{
DefaultSaveExcel(Excel.ActiveWorkbook,ref Cancel);
if (!Cancel)
{
//if enters here is because the workbook is actually closing
Delete(Excel.ActiveWorkbook.Name);
}
}
public void DefaultSaveExcel(Workbook wb, ref bool Cancel)
{
while (wb.Saved == false && Cancel == false)
{
var result = ShowMessageDialogSave();
if (result == System.Windows.Forms.DialogResult.Yes)
{
var sa = CreateExcelSaveDialog(wb.FullName);
if (sa.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{
wb.SaveAs(sa.FileName);
wb.Save();
}
}
else if (result == System.Windows.Forms.DialogResult.No)
{
wb.Saved = true;
}
else if (result == System.Windows.Forms.DialogResult.Cancel)
{
Cancel = true;
}
}
}
public System.Windows.Forms.SaveFileDialog CreateExcelSaveDialog(string name = null)
{
var sa = new System.Windows.Forms.SaveFileDialog();
sa.Filter = "Excel files (*.xlsx)|*.xlsx";
if (!string.IsNullOrEmpty(name))
sa.FileName = name;
sa.CreatePrompt = true;
return sa;
}
public DialogResult ShowMessageDialogSave()
{
var app = (Microsoft.Office.Interop.Excel.Application)ExcelDna.Integration.ExcelDnaUtil.Application;
NativeWindow xlMain = new NativeWindow();
xlMain.AssignHandle(new IntPtr(app.Hwnd));
var message = "Do you want to save pending changes?";
if (Thread.CurrentThread.CurrentCulture.TwoLetterISOLanguageName.ToLower() == "es")
message = "¿Desea guardar los cambios pendientes?";
return System.Windows.Forms.MessageBox.Show(xlMain, message, "Microsoft Excel", System.Windows.Forms.MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning,MessageBoxDefaultButton.Button1);
}
public override void OnBeginShutdown(ref Array custom)
{
base.OnBeginShutdown(ref custom);
//I PUT MY CUSTOM CODE HERE:
CloseAllPanes();
ExcelTaskExecutor.Destroy();
}
现在,如果用户选择单击“保存”对话框上的“取消”,OnBeginShutdown()将不会运行,我的窗格仍在那里
不管怎么说,你的方法很酷,如果不是你的帮助,我从来没有机会弄清楚到底发生了什么,谢谢你让我走上找到这个解决方案的轨道 我刚刚尝试了这个,单击“取消”后,我的加载项仍然加载。当然Excel不会卸载您的外接程序-您确定这就是正在发生的事情吗?嗨,Jim!谢谢你的回复。您使用的是什么版本的Excel DNA?0.34.6。如果您仔细想想,当用户保持Excel打开时,Excel卸载所有加载项确实是一个错误。为什么您认为它正在卸载您的加载项?肯定还有其他原因。是否可能在代码中的某个地方订阅了event WorkbookBeforeClose?就我而言,即使您单击“取消”按钮,也会触发此事件。elarmando,您的位置正确!问题是,在WorkbookBeforeClose中,有一些操作可以清除侧窗格的所有内容,如您所说,即使单击“取消”,也会触发这些操作。是否有一个解决方法,在工作表关闭时做一些事情。。。我正在试图找到一种方法来知道工作簿是否真的关闭了,或者类似的解决方法,以便设置一个标志,这样我就可以运行我的代码了。谢谢,这真的很有帮助