Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/294.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Excel DNA加载项在以下情况下卸载;是否要保存“提示”;选择“取消”按钮_C#_Html_Excel_Wpf_Excel Dna - Fatal编程技术网

C# 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方法)。由于工作簿已保

当我按File->Exit(或Alt+F4)或X时,我会收到“是否保存更改”对话框的提示,在该对话框中我可以选择“取消”。因此Excel可以继续,但我的Excel dna外接程序再也不会收到通知,并保持卸载状态


提前谢谢各位

据我所知,在用户单击“取消”之前执行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中,有一些操作可以清除侧窗格的所有内容,如您所说,即使单击“取消”,也会触发这些操作。是否有一个解决方法,在工作表关闭时做一些事情。。。我正在试图找到一种方法来知道工作簿是否真的关闭了,或者类似的解决方法,以便设置一个标志,这样我就可以运行我的代码了。谢谢,这真的很有帮助