Приложение остается открытым при использовании Owner.Show() для основной формы

Я получил две формы, основную и вторую. Поскольку я хочу легко перемещаться между ними, избегая создания нескольких экземпляров каждого, я использовал это в главной форме:

Form2 secondForm = new Form2();
private void btnForm2_Click(object sender, EventArgs e)
{
 secondForm.Show(this);
 Hide();
}

и код ниже во второй форме:

private void Form2_FormClosing(object sender, FormClosingEventArgs e)
{ 
 e.cancel = true;
 Owner.Show();
 Hide();
}

Все работает просто отлично, кроме того, что я не могу закрыть приложение. Когда я перехожу во вторую форму и возвращаюсь к основному, кнопка закрытия вообще ничего не работает.

Как я могу закрыть программу, пока я все еще использую этот код?

Я также попробовал этот код, чтобы увидеть, работает ли кнопка закрытия сама:

 private void Form1_FormClosing(object sender, FormClosingEventArgs e)
 {
      MessageBox.Show("Closing");
 } 

MessageBox был показан, но после этого ничего не произошло.

4 ответа

Решение

Это происходит потому, что вторая форма не закрыта - вы используете для нее e.cancel = true. Добавьте следующую строку, если вы хотите принудительно закрыть все окна приложения

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
 {
     System.Windows.Forms.Application.Exit();
 } 

затем в form2 вы можете проверить, направлено ли закрытие от пользователя или из приложения:

void Form2_FormClosing(object sender, FormClosingEventArgs e)
{
 //close button click by user on form 2
    if(e.CloseReason == CloseReason.UserClosing)
        e.cancel = true //cancel event
   else
     e.cancel = false //close this form
}

Или вы можете использовать CloseReason.UserClosing для направления вашей отмены в зависимости от родства. Например:

 void Form2_FormClosing(object sender, FormClosingEventArgs e)
    {

//check if closing signal is from parent
       if   (e.CloseReason == CloseReason.UserClosing.FormOwnerClosing)
         e.cancel = false //close this form
      else 
          e.cancel = true 
    }

Использование

Environment.Exit(0);

закрывать

Я предпочитаю простые решения.

В Form1_FormClosing используйте:

secondForm.Close();

А вот и изюминка. В Form2_FormClosing оберните код, который у вас уже есть:

if (this.Visible)
{
    ...
}

И это работает для меня. Когда я закрываю основную форму, она закрывается, поскольку Form2 не видна и не знает, чтобы отменить закрытие.

Поскольку в ответе указана Environment.Exit(0); получил голосование, см. winforms - Как правильно выйти из приложения C#? - Переполнение стека. Он цитирует MSDN, говоря, что это для консольных приложений. Я не вижу этого в текущей документации, но она все еще актуальна. Также см. Application.Exit() против Application.ExitThread() против Environment.Exit (). Похоже, что соглашение между Environment.Exit, Application.ExitTread и Application.Exit, Application.Exit представляется наилучшим. Однако я не буду использовать ни один из них, кроме как ненормально прекратить работу моего приложения, например, из-за ошибки.

Закрытие Form1 "пытается" закрыть форму2. Запускает событие Form2_Closing, которое отменяет закрытие и запускает form1.

Код с отменой подписки на события (быстрый и грязный), обратите внимание на внутренний модификатор в Form2. Вы можете рассмотреть вопрос о том, чтобы сделать подписку "Стоп / начать" в качестве методов

    private void btnForm2_Click(object sender, EventArgs e)
    {

        secondForm.FormClosing += secondForm.Form2_FormClosing;
        secondForm.Show(this);
        Hide();
    }

    internal void Form2_FormClosing(object sender, FormClosingEventArgs e)
    {
        e.Cancel = true;



        FormClosing -= Form2_FormClosing;
        Owner.Show();
        Hide();
    }

После публикации я понял, что вы можете использовать свойство FormClosingEventArgs.CloseReason для более простого решения:

private void Form2_FormClosing(object sender, FormClosingEventArgs e)
    {
        if (e.CloseReason == CloseReason.FormOwnerClosing) { return; }
        e.Cancel = true;
        Owner.Show();
        Hide();


    }
Другие вопросы по тегам