我目前正在开发Excel VSTO插件,这是WorkbookBeforeClose的代码
private void App_WorkbookBeforeClose(Excel.Workbook Wb, ref bool Cancel)
{
bool isEnabled = false;
setRibbonControlState(ref isEnabled);
}
在此代码中,如果没有打开的工作簿,则禁用功能区。但是,如果我在尝试关闭Excel之后从对话框中按“取消”按钮,则功能区还是会被禁用。但是,由于WorkbookBeforeClose事件传递了一个Cancel参数,因此当我按下按钮时,我不知道如何设置该参数,如何检查提示您已触发按钮的对话框。
到目前为止,我已经看到的所有情况都在WorkbookBeforeClose处理程序的主体中实现了一个对话框,但是我不想实现自定义对话框,我想使用默认提供的对话框。
谢谢!
截至我的VBA经验
但我不想实施自定义对话框,我想使用默认提供的对话框。
不可能,因为该对话框仅在before_close
事件之后出现。唯一(据我所知)管理这些内容的方法-创建自己的SaveChanges对话框,顺便说一句,这是非常简单的,并非每个用户都会注意到差异。而且,它将执行与默认提示相同的工作。您还应注意的另一件事-可能至少有一个看不见的工作簿。即使您看到这样的屏幕:this.Application.Workbooks.Count
可能会显示1,而不是0。这是由于用户有自己的Personal.xlsb工作簿的可能性,该工作簿是不可见的,但仍加载有Excel.Application。因此,如果您要正确禁用功能区-您也应该考虑这一点。
这是此解决方案的示例:
public partial class ThisAddIn
{
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
this.Application.WorkbookBeforeClose += ApplicationOnWorkbookBeforeClose;
}
private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
{
}
// Catch the before close event
private void ApplicationOnWorkbookBeforeClose(Excel.Workbook wb, ref bool cancel)
{
if (!wb.Saved)
{
switch (MessageBox.Show(text:$"Do you want to save changes you made to '{this.Application.ActiveWorkbook.Name}'?",
caption:"Microsoft Excel",buttons:MessageBoxButtons.YesNoCancel, icon:MessageBoxIcon.Exclamation))
{
case DialogResult.Cancel: // case want to cancel - break the closing event
{
cancel = true;
return;
}
case DialogResult.Yes: // case user want to save wb - save wb
{
wb.Save();
break;
}
case DialogResult.No: // case user don't want to save wb - mark wb as saved to avoid the application messagebox to appear
{
wb.Saved = true;
break;
}
}
}
if (IsAnyWorkbookOpen())
{
// replace this with your code
MessageBox.Show("Some books will still be open, don't turn off the ribbon");
return;
}
// replace this with your code
MessageBox.Show("All books will be closed");
}
private bool IsAnyWorkbookOpen()
{
// check that remaining amount of open workbooks without the one being closed is greater that 2
if (this.Application.Workbooks.Count - 1 > 2)
{
return true;
}
// IF the count of workbooks is 2 one of them maybe a PERSONAL.xlsb
else if (this.Application.Workbooks.Count == 2)
{
foreach (Excel.Workbook wb in this.Application.Workbooks)
{
if (!wb.Name.Equals(this.Application.ActiveWorkbook.Name))
{
// In case when one of two open workbooks is Personal macro book you may assume that
// there will be no open workbooks for user to work directly
if (wb.Name.Equals("Personal.xlsb".ToUpper()))
{
return false;
}
}
}
// In case when NONE of two open workbooks is a Personal macro book
// there will be at least one open workbook for user to work directly
return true;
}
else
{
return true;
}
}
#region VSTO generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InternalStartup()
{
this.Startup += new System.EventHandler(ThisAddIn_Startup);
this.Shutdown += new System.EventHandler(ThisAddIn_Shutdown);
}
#endregion
}
还有最后一件事-如果禁用功能区,但应用程序仍在运行-您将不得不在workbook_activate
事件中再次启用它。
[Note我只是从VBA转到VSTO-因此,任何评论都将受到高度赞赏。