способы закрытия формы
Пользователь пытается закрыть программу стандартным способом, кликает на верхнюю правую кнопку «крестик», нажимает комбинацию клавиш Alt+F4 или в левом верхнем углу вызывает контекстное меню формы. Но программа сразу не закрывается, а появляется окно сообщения, в котором нужно подтвердить решение закрытия.
Событие FormClosingEventArgs принимает параметр «е». Этот параметр имеет свойство Cancel. Если установить его в false , форма закроется, если в true — останется открытой.
Копировать
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Windows.Forms;
- namespace _0006
- public partial class Form1 : Form
- public Form1()
- InitializeComponent();
- >
- private void Form1_FormClosing( object sender, FormClosingEventArgs e)
- DialogResult dialog = MessageBox.Show(
- «Вы действительно хотите выйти из программы?» ,
- «Завершение программы» ,
- MessageBoxButtons.YesNo,
- MessageBoxIcon.Warning
- );
- if (dialog == DialogResult.Yes)
- e.Cancel = false ;
- >
- else
- e.Cancel = true ;
- >
- >
- >
- >
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Windows.Forms;
- namespace _0006
- public partial class Form1 : Form
- public Form1()
- InitializeComponent();
- >
- private void Form1_FormClosing( object sender, FormClosingEventArgs e)
- DialogResult dialog = MessageBox.Show(
- «Вы действительно хотите выйти из программы?» ,
- «Завершение программы» ,
- MessageBoxButtons.YesNo,
- MessageBoxIcon.Warning
- );
- if (dialog == DialogResult.Yes)
- e.Cancel = false ;
- >
- else
- e.Cancel = true ;
- >
- >
- >
- >
Form. Form Closing Событие
Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Происходит перед закрытием формы.
public: event System::Windows::Forms::FormClosingEventHandler ^ FormClosing;
public event System.Windows.Forms.FormClosingEventHandler FormClosing;
public event System.Windows.Forms.FormClosingEventHandler? FormClosing;
member this.FormClosing : System.Windows.Forms.FormClosingEventHandler
Public Custom Event FormClosing As FormClosingEventHandler
Тип события
Примеры
В следующем примере показано использование этого элемента. В этом примере обработчик событий сообщает о возникновении FormClosing события. Этот отчет поможет вам узнать, когда происходит событие, и поможет вам в отладке. Чтобы сообщить о нескольких событиях или о событиях, которые происходят часто, рекомендуется заменить MessageBox.ShowConsole.WriteLine сообщение или добавить его в многостроочный TextBox.
Чтобы выполнить пример кода, вставьте его в проект, содержащий экземпляр типа Form с именем Form1 . Затем убедитесь, что обработчик событий связан с событием FormClosing .
private void Form1_FormClosing(Object sender, FormClosingEventArgs e) < System.Text.StringBuilder messageBoxCS = new System.Text.StringBuilder(); messageBoxCS.AppendFormat("= ", "CloseReason", e.CloseReason ); messageBoxCS.AppendLine(); messageBoxCS.AppendFormat(" = ", "Cancel", e.Cancel ); messageBoxCS.AppendLine(); MessageBox.Show(messageBoxCS.ToString(), "FormClosing Event" ); >
Private Sub Form1_FormClosing(sender as Object, e as FormClosingEventArgs) _ Handles Form1.FormClosing Dim messageBoxVB as New System.Text.StringBuilder() messageBoxVB.AppendFormat(" = ", "CloseReason", e.CloseReason) messageBoxVB.AppendLine() messageBoxVB.AppendFormat(" = ", "Cancel", e.Cancel) messageBoxVB.AppendLine() MessageBox.Show(messageBoxVB.ToString(),"FormClosing Event") End Sub
Комментарии
Событие FormClosing возникает при закрытии формы. При закрытии формы она удаляется, освобождая все ресурсы, связанные с формой. Если отменить это событие, форма останется открытой. Чтобы отменить закрытие формы, задайте Cancel для свойства объекта , переданного FormClosingEventArgs обработчику событий, значение true .
Если форма отображается как модальное диалоговое окно, нажатие кнопки Закрыть (кнопка с X в правом верхнем углу формы) приводит к скрытию формы, а DialogResult свойству — значение DialogResult.Cancel . Вы можете переопределить значение, присвоенное свойству DialogResult , когда пользователь нажимает кнопку Закрыть , задав DialogResult свойство в обработчике FormClosing событий для события формы.
При вызове Close метода в , отображаемом Form как немодированное окно, нельзя вызвать Show метод , чтобы сделать форму видимой, так как ресурсы формы уже освобождены. Чтобы скрыть форму и сделать ее видимой Hide , используйте метод .
Если форма является родительской формой FormClosing многодокументного интерфейса (MDI), события всех дочерних форм MDI вызываются перед событием родительской FormClosing формы MDI. Аналогичным образом события FormClosed всех дочерних форм MDI вызываются перед событием FormClosed родительской формы MDI. Отмена FormClosing события дочерней формы MDI не препятствует возникновению FormClosing события родительской формы MDI. Однако при отмене события будет задано true Cancel свойство FormClosingEventArgs класса , которое передается в качестве параметра в родительскую форму. Чтобы принудительно закрыть все родительские и дочерние формы MDI, присвойте свойству Cancel значение false в родительской форме MDI.
Дополнительные сведения об обработке событий см. в разделе Обработка и вызов событий.
Как открыть и закрыть форму из другой формы в C# (правильное решение)

C# изучаю не так давно и встала передо мной недавно задача:
— открыть Form2 при нажатии на кнопку в Form1;
— спрятать Form1;
— открыть Form1 при закрытии Form2.
На первый взгляд задача показалась элементарной, но… возникли нюансы — при закрытии приложения оно не выгружалось и в диспетчере задач мы наблюдали его работу, хотя визуально оно как бы закрылось.
В чём же причина такого поведения? Об этом расскажу дальше. Рассмотрим открытие и закрытие форм на примерах.
Открываем и закрываем форму из другой формы
У нас в приложении есть две формы Form1 — главная, которая открывается сразу при запуске приложения и Form2, которую открываем по нажатию на кнопку.
Чтобы открыть Form2 нам необходим следующий код, который будет срабатывать при нажатии на кнопку:
private void button1_Click(object sender, EventArgs e)
Теперь у нас открылась Form2 и спряталась Form1. Поработав с Form2 мы её закрываем и при этом нам надо после этого отобразить Form1. Многие начинающие, включая меня начинают писать следующий код, который помещаем в событие, которое происходит после закрытия Form2:
private void Form2_FormClosed(object sender, FormClosedEventArgs e)
Вроде всё логично: Form2 закрылась, Form1 открылась. Однако используя этот метод, мы можем заметить, что после того как мы закрываем приложение оно продолжает висеть в памяти. Многие, не зная почему это происходит дописывают в метод «Form1_FormClosed» дописывают принудительное закрытие приложения:
Application.Exit();
Это работает, однако правильно ли это? Решать вам.
А теперь ответим на вопрос «почему приложение висит в памяти» и рассмотрим простое и правильное решение.
Первая часть кода: мы отображаем Form2 и скрываем Form1. Не закрываем, а именно скрываем, т.е. экземпляр Form1 продолжает существовать.
Закрыть Form1 вместо скрытия не получится, так как это главная форма приложения и при её закрытии мы закроем всё приложение.
Вторая часть кода: строкой «Form ifrm = new Form1();» мы создаём второй экземпляр Form1 и далее его и отображаем, а первый экземпляр Form1 продолжает жить в памяти. И когда мы закрываем приложение (Form1), то первый экземпляр при этом не закрываем он так и «сидит» в памяти, поэтому приложение не выгружается из памяти. В связи с этим многие и закрывают принудительно приложение при закрытии главной формы (Form1).
Сейчас мы с вами рассмотрим правильный код, который не будет создавать второй экземпляр Form1 и отображать его, а будет отображать скрытую до этого Form1.
private void Form2_FormClosed(object sender, FormClosedEventArgs e)
OpenForms — получает коллекцию открытых форм приложения. В нашем случае мы сразу обратились к главной форме приложения (OpenForms[0]).
Теперь при закрытии Form2 у нас будет вызываться и отображаться та форма, которая породила закрывающуюся.
Учитываем координаты форм при открытии
Представьте ситуацию. Открыта Form1 вы её перемещаете в правый верхний угол экрана. Потом нажимаете на кнопку и… Form2 открывается по центру экрана или в другом месте, но не в том месте, где была Form1. Многие улыбнуться и скажут, что в свойствах Form2 надо прописать/указать следующее «StartPosition -> CenterParent» и открывать Form2 следующим методом:
Form ifrm = new Form2(); ifrm.ShowDialog();
Это правильное решение, которое всегда будет открывать Form2 поверх Form1 и всегда по центру Form1. Однако этот код не применим, если вам надо скрывать Form1, так как Form1 не будет скрываться.
Сейчас приведу полное решение, которое позволит открывать Form1 и Form2 в той же точке, где находилась до этого форма, вызывающая другую форму. Код включает всё вышеописанное. В свойствах форм надо прописать следующее (прямо в студии выбираете эти значения):
— свойство Form1: «StartPosition -> CenterScreen»
— свойство Form2: «StartPosition -> Manual»

private void button1_Click(object sender, EventArgs e)
private void Form2_FormClosed(object sender, FormClosedEventArgs e)
Теперь вы не создаёте второго экземпляра Form1 и приложение всегда будет закрываться, не оставаясь в памяти.
Открываем форму поверх другой формы, как модальное окно
Чтобы открыть Form2 поверх Form1, как модальное окно, не скрывая Form1, вам хватит этого кода:
private void button1_Click(object sender, EventArgs e)
В итоге Form2 будет открыта поверх Form1. В этом случае пользователь не сможет переключиться на Form1 не закрыв Form2.

Предыдущая запись

Следующая запись
Отличная статья, как раз решило мою идентичную проблему, автору удачи в дальнейшем и спасибо за помощь.
вроде стать о том как с одной формы закрыть другу?! причем тут скрытие/закрытие первой открытия второй и на оборот.
C# Как грамотно закрыть Form?
Здравствуйте, коллеги! Не думал, что будут проблемы с такими вот вещами, но тем не менее. Вот в чем суть проблемы. Разрабатываю программу, в которой из главной Form1, при нажатии на копку я открываю Form2.
private void button5_Click(object sender, EventArgs e)
Далее уже на Form2 я выполняю код, который заполняет таблицу на Form1, при этом я вывожу данные в таблицу, а затем мне нужно закрыть Form2 сразу.
Form1 f = new Form1(); ////// Та та та здесь код запонения таблицы на Form1 f.ShowDialog(); Application.Exit();
Так вот в чем проблема: Form2 она то вроде закрывается, но по факту только скрывается. По долгу своей работы, мое приложение должно работать сутками в фоне и получается, что очередной раз пользователь открывает Form2, нажимает там на кнопку, таблица на Form1 заполняется, но Form2 не закрывается, а сворачивается. И так у меня плодятся окна Form1 и Form2 до бесконечности. Как можно это грамотно обыграть? P.s. Пробовал и Form2.ActiveForm.Close() и this.Close() ничего не помогает. Может логическая ошибка где? Помогите, пожалуйста!
Отслеживать
задан 9 фев 2018 в 22:37
97 1 1 золотой знак 1 1 серебряный знак 6 6 бронзовых знаков
подозреваю, вам нужно пересмотреть подход к решению проблемы. попробуйте один раз создавать формы, а потом скрывать/отображать. подробнее: victorz.ru/20160519140
9 фев 2018 в 22:52
Т.е. вы хотите сказать, что код в обработчике события нажатия кнопки в Form2 вида this.Close() не работает? И форма просто меняет свойство Visible на false ? Полагаю, что вы смастерили семиколёсный велосипед в передаче данных между формами, отчего и страдаете. Получить доступ к форме, не важно к какой, можно так: Form1 form1 = (Form1)Application.OpenForms[«Form1»]; , а дальше через делегаты обращайтесь к её методам и переменным как хотите. А через оператор new вы создаёте новый экземпляр объекта. Да и Application.Exit(); — это вообще из другой оперы.
9 фев 2018 в 23:26
3 ответа 3
Сортировка: Сброс на вариант по умолчанию
После закрытия формы через Close() вызовите в первой форме у второй Dispose() и будет вам счастье. Иногда достаточно почитать официальные мануалы.
Два условия, когда форма не удаляется при вызове Close это когда (1) это часть приложения многодокументного интерфейса (MDI) и форма не является видимой; и (2) форма была отображена посредством ShowDialog.
Отслеживать
ответ дан 9 фев 2018 в 23:00
1,099 6 6 серебряных знаков 8 8 бронзовых знаков
Пример обработчика события по нажатию кнопки в Form2 с изменением свойств объектов формы Form1.
private void buttonChangeDataForm1_Click(object sender, EventArgs e) < Form1 form1 = (Form1) Application.OpenForms["Form1"]; // Где Form1 это имя формы содежащаяся в переменной Name. if (form1 != null) // Если форма существует, то изменяем свойства её объектов < form1.textBox.Text = "Bla Bla BLa"; . this.Close(); // Закрываем текущую форму >else MessageBox.Show("Error while changing data in Form1.", "Error"); // Выводим сообщение об ошибке изменения данных >
Пример более правильного вызова/создания дочерней формы.
private void buttonCreateForm2_Click(object sender, EventArgs e) < Form2 form2 = (Form2) Application.OpenForms["Form2"]; // Где Form2 это имя формы содежащаяся в переменной Name. if (form2 == null) // Если форма не существует, то создаём < Form2 form2 = new Form2(); // Создание нового экземпляра формы form2.Show(); // Отображаем форму >else form2.Activate(); // Активируем форму на передний план (из трея или заднего плана) >
Настоятельно рекомендую иметь ввиду контроль наличия (существования) окна, если вы используете окно без привязки к основному. Т.е. если дочерние окна можно убрать в фон или на задний план, то вы обязательно его потеряете.
Имена форм для Application.OpenForms[«AnyFormName»]; находятся в свойствах самих форм в переменной Name . Изменить (переопределять не стоит) можно в классе *.Designer.cs .
Если вам необходим доступ к методам формы, то необходимо создавать для них делегаты методов перед использованием.
P.S. Если предполагается использование дочернего окна ввод данных в которое обязателен для продолжения работы программы, то никогда не позволяйте это окно убирать в трей. Оно будет всегда поверх основного и его можно либо обработать вводом данных, либо закрыть. Так вы обезопасите себя от потери контроля над формами. И в этом случае вам нет необходимости контролировать наличие окна при его создании, т.к. доступ к основной форме будет ограничен. Достаточно будет выполнить код:
Form form2 = new form2(); form2.ShowDialog();