2016-06-28 8 views
2

У меня есть приложение Winforms, которое создает электронную таблицу Excel с помощью Excel Interop.Почему FormDeactivate вызывается до закрытия формы?

Когда я попытался сохранить лист таким образом:

_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 = COM-объект, который был отделен от его базового RCW, не может быть использован. «

Это не имело большого смысла, хотя - я не делал ничего интересного нитями или такими; это довольно простая утилита для ванили. Единственные другие места _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 выбывает, была вызвана из Деактивировать события формы, которая была:

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

Проблема заключалась в том (что я обнаружил после сдачи контрольных точек во всех местах, где ссылочные _xlBook), что FormMain_Deactivate() вызывается до Вызывается _xlBook.SaveAs(), который вызывается при нажатии кнопки «Выполнить».

После того, как я прокомментировал вызов DeinitializeExcelObjects() в FormMain_Deactivate() и вызвал его сразу после вызова функции _xlBook.SaveAs(), он отлично работает - файл создается и сохраняется без каких-либо ошибок msg.

Итак, почему FormDeactivate вызывается до того, как форма закрыта? Если это каким-то образом «спроектировано», событие ужасно прозвано.

+1

Ну 'Деактивировать' вызывается в любое время, когда' Form' теряет фокус, поэтому разумно, что его вызывали при закрытии. И это * * согласуется с методом 'Form.Активировать() '. – InBetween

+0

Правильно, но в это время он не должен закрываться. –

+0

Что заставляет вас думать, что он закрывается? Кнопка «Запустить» делает больше, чем просто «SaveAs»? Я могу представить, что форма деактивируется, когда, например, вы запрашиваете у пользователя имя целевого файла? –

ответ

4

Вы внесли свой код в неправильное место. :-) Кажется, вы неправильно поняли, что означает активация и деактивация (по крайней мере, что касается Windows).

Деактивация происходит всякий раз, когда активируется другое окно, и ясно, когда ваша форма уничтожается, другое окно должно стать активным, даже если это окно является рабочим столом Windows. FormDeactivate можно вызывать несколько раз (например, когда пользователь переключается на другое приложение или даже в другое окно в вашем собственном приложении). Важно отметить, что это также относится к активации ; FormActivate может срабатывать многократно.

Если вы хотите, чтобы код запускался, когда ваша форма закрывается, поместите его в обработчик события FormClose.