Закрытие диспетчера задач не обнаружено во второй раз в приложении WinForms

StackOverflow https://stackoverflow.com/questions/2565041

Вопрос

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
    if (e.CloseReason == CloseReason.UserClosing)
    {
        if (MessageBox.Show(this, "Do you really want to close?", "Close?", 
                            MessageBoxButtons.YesNo) == DialogResult.No)
        {
            e.Cancel = true;
        }
    }
}

Поэтому, когда я хочу закрыть приложение, нажав на кнопку закрыть, окно сообщения отображается как положено, затем я выбрал "Нет".Затем выполняется строка e.Cancel = true, и форма не закрывается.

Теперь дело в том, что после этого, если я закрою приложение из диспетчера задач, причиной закрытия будет закрытие пользователя!!!Почему?Разве это не должно быть TaskManagerClosing?

Это было полезно?

Решение

Я нашел Нитки с ответом от нашего собственного автора нобугз:

Windows Forms не удается определить, что причина закрытия была вызвана диспетчером задач .Таким образом, это автоматически преобразует CloseReason.None в CloseReason.TaskManagerClosing.Проблема в том, что после того, как вы попытались закрыть с помощью "X", причина закрытия устанавливается в UserClosing и не сбрасывается обратно в None, если вы отмените закрытие.Неаккуратно.

И рядом с ним объяснение другого пользователя о том, как изменить значение e.CloseReason на None, используя отражение (поскольку оно доступно только для чтения), чтобы обойти эту проблему (это следует применять при установке e.Cancel значения True):

FieldInfo fi = typeof(Form).GetField("closeReason", BindingFlags.Instance | BindingFlags.NonPublic);

fi.SetValue(this, CloseReason.None);

Другие советы

См. отвечать на этот вопрос, который использует CloseReason.TaskManagerClosing поймать то же самое.

Просто перевод вашего кода в VB:

Imports System.Reflection
Private Sub ResetCloseReason()
  Dim myFieldInfo As FieldInfo
  Dim myType As Type = GetType(Form)
  myFieldInfo = myType.GetField("closeReason", BindingFlags.NonPublic Or _
                    BindingFlags.Instance Or BindingFlags.Public)
  myFieldInfo.SetValue(Me, CloseReason.None)

End Sub

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top