c# - 为什么在关闭表单之前调用 FormDeactivate?

标签 c# winforms excel-interop winforms-interop

我有一个 Winforms 应用程序,可以使用 Excel Interop 生成 Excel 电子表格。

当我尝试以这种方式保存工作表时:

_xlBook.SaveAs(filename, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Excel.XlSaveAsAccessMode.xlExclusive, Type.Missing, Type.Missing, Type.Missing, Type.Missing, Type.Missing);

...它会失败,告诉我,“System.Runtime.InteropServices.InvalidComObjectException 未处理 HResult=-2146233049 Message=已与其底层 RCW 分离的 COM 对象无法使用。"

但这并没有多大意义——我并没有对线程之类的东西做任何花哨的事情;这是一个非常简单的普通实用程序。代码中唯一引用 _xlBook 的其他位置是:

1)

private Excel.Workbook _xlBook;

2)

_xlBook = _xlApp.Workbooks.Add(Type.Missing);

3)

_xlSheets = _xlBook.Worksheets;
_xlSheet = (Excel.Worksheet)_xlSheets.Item[1];

4)

_xlBook.Close(false);
Marshal.ReleaseComObject(_xlBook);

最后一部分,即 _xlBook 被释放的地方,是从表单的 Deactivate 事件中调用的,该事件是:

private void FormMain_Deactivate(object sender, EventArgs e)
{
    DeinitializeExcelObjects();
}

问题是(我在引用 _xlBook 的所有位置放置断点后发现),FormMain_Deactivate() 在调用 _xlBook.SaveAs() 之前被调用,而 _xlBook.SaveAs() 被调用时单击“运行”按钮。

一旦我在 FormMain_Deactivate() 中注释掉对 DeinitializeExcelObjects() 的调用,并在调用 _xlBook.SaveAs() 之后立即调用它,它就可以正常工作 - 文件被创建并保存,没有任何错误消息。

那么为什么在表单关闭之前调用 FormDeactivate 呢?如果这在某种程度上是“按照设计的”,那么该事件的命名就严重错误了。

最佳答案

您将代码放在了错误的位置。 :-) 看来您误解了激活和停用的含义(至少就 Windows 而言)。

只要激活不同的窗口,就会发生停用,显然,当您的表单被销毁时,另一个窗口必须变为事件状态,即使该窗口是 Windows 桌面。 FormDeactivate 可以被多次调用(例如当用户切换到不同的应用程序,甚至是您自己的应用程序中的不同窗口时)。值得注意的是,这也适用于激活; FormActivate 也可以多次触发。

如果您希望代码在关闭表单时运行,请将其放入 FormClose 事件处理程序中。

关于c# - 为什么在关闭表单之前调用 FormDeactivate?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38086915/

相关文章:

c# - 免费/开源 WinForms Skinner?

c# - 与不可见网格的 Irrlich 碰撞

c# - Telerik OpenAccess。使用其他类型的集合而不是 IList<T>

c# - 从 C# 运行 CMD.exe 时系统找不到指定的文件

c# - 非常简单的 2d 和 3d 图形库

c# - 使用我添加我的项目的形式

c# - 通过添加 UTC 偏移将 Twitter DateTime 转换为本地时间

c# - 从excel工作簿中删除非空工作表

c# - Excel Interop - 保护工作表不包括列

c# - Microsoft Office Interop Excel 12.0 无法在 IIS 7 中工作