Обработчик кнопки главной формы которая открывает дочернее окно.
private void button1_Click(object sender, EventArgs e)
{
Form2 mainForm = new Form2(this); // передаю управление дочерней форме
mainForm.ShowDialog();
}
Конструктор дочерней формы
public Form2(Form1 f)
{
InitializeComponent();
f.Close();
}
В итоге закрываются обе формы при открытии дочерней.
Если в Visual Studio создать новый WinForms проект и посмотреть код в файле Program.cs, можно увидеть что приложение запускается вот такой строчкой:
Application.Run(new Form1());
Этот код неявно создает новый экземпляр ApplicationContext, который подписывается у переданной формы на событие FormClosed. Когда возникает событие FormClosed
, ApplicationContext
вызывает метод Application.ExitThread, который закрывает все окна и завершает приложение.
Можно сделать свой собственный ApplicationContext, что позволяет управлять жизненным циклом приложения по своему усмотрению. Вот такое приложение, например, никогда самостоятельно не завершается, его нужно будет завершать из диспетчера задач.
public class MyApplicationContext :ApplicationContext {
public MyApplicationContext(Form startupForm) {
startupForm.Show();
}
}
// ..
Application.Run(new MyApplicationContext(new Form1()));
Для того, чтобы завершить приложение тогда и только тогда, когда закроется самая распоследняя форма, можно использовать свойство Application.OpenForms для проверки наличия хотя бы одной открытой формы.
public class MyApplicationContext :ApplicationContext {
public MyApplicationContext(Form startupForm) {
startupForm.FormClosed += OnFormClosed;
startupForm.Show();
}
private void OnFormClosed(object sender, FormClosedEventArgs e) {
if (Application.OpenForms.Count > 0) {
foreach (Form form in Application.OpenForms) {
form.FormClosed -= OnFormClosed;
form.FormClosed += OnFormClosed;
}
}
else ExitThread();
}
}
Теперь главное только следить за тем, чтобы у пользователя была возможность закрыть все формы. Нельзя допускать чтобы последняя форма не имела кнопки в правом верхнем углу и не обрабатывала Alt+F4.
Однако, если применить описанный выше подход в вашем примере, он все равно не сработает.
Вы закрываете вызывающую форму в конструкторе дочерней. В этот момент дочерняя форма все еще не открыта, и Application.OpenForms
окажется пустым, что приведет к завершению приложения.
Можно перенести код, закрывающий вызывающую форму в метод OnShown
.
public partial class Form2 : Form {
private Form PrevForm;
private Form2() {
InitializeComponent();
}
public Form2(Form f) : this() {
PrevForm = f;
}
protected override void OnShown(EventArgs e) {
base.OnShown(e);
PrevForm.Close();
PrevForm = null;
}
}
А проще сделать так, чтобы вызывающая форма закрывала сама себя.
private void simpleButton1_Click(object sender, EventArgs e) {
Form2 mainForm = new Form2(this); // передаю управление дочерней форме
mainForm.ShowDialog();
Close();
}
Метод ShowDialog открывает модальное окно. Оно зависит от родительского окна, и закрывается вместе с ним. Если вызывающая форма это единственное открытое окно на данный момент, она автоматически становится родительской для Form2
. Для того, чтобы разорвать связь с вызывающей формой, показывайте Form2
с помощью метода Show.
В описанном сценарии, вам наверняка нет нужды, чтобы форма, которую вы показали первоначально, оставалась висеть в памяти после ее закрытия. Однако, Form1
это локальная переменная метода Main
. Ссылка на Form1
будет хранится на стеке до тех пор, пока приложение не завершатся.
Чтобы не создавать локальную переменную, можно изменить MyApplicationContext таким образом, что он будет самостоятельно создавать самую первую форму в своем конструкторе. Например, передать в конструктор не экземпляр формы, а ссылку на метод, который этот экземпляр может создать.
public MyApplicationContext(Func<Form> formFactory) {
Form startupForm = formFactory();
startupForm.FormClosed += OnFormClosed;
startupForm.Show();
}
// ..
Application.Run(new MyApplicationContext(() => new Form1()));
Идея в том, что приложение начинается с формы ввода логина и пароля, эта форма появляется первой, а значит главная. После нажатия баттона Log In форма ввода логина и пароля исчезает и появляется основное окно.
public class MyApplicationContext :ApplicationContext {
public MyApplicationContext() {
Form loginForm = new LoginForm();
loginForm.UserCancelledLogin += OnUserCancelledLogin;
loginForm.UserAuthorized += OnUserIsAuthorised;
}
private void OnUserCancelledLogin(object sender, EventArgs e) {
ExitThread();
}
private void OnUserAuthorised(object sender, EventArgs e) {
Form loginForm = (Form)sender;
loginForm.Close();
Form mainForm = new MainForm();
mainForm.FormClosed += OnformClosed();
mainForm.Show();
}
private void OnFormClosed(object sender, FormClosedEventArgs e) {
ExitThread();
}
}
Это зависит от того, как запущено ваше приложение. Если ваше приложение просто ожидает закрытия главной формы - то когда вы её закрываете, происходит выход из приложения, при этом закрываются все остальные формы.
Да и смысл закрывать основную форму? Вы больше к ней не планируете возвращаться?
Если таки вам надо основную форму убрать с экрана, вы можете её скрыть, например, так
Form2 mainForm = new Form2(); // передаю управление дочерней форме
this.Hide();
mainForm.ShowDialog();
Ну, и, например, если после закрытия дочерней формы нужно снова показать главную
Form2 mainForm = new Form2(); // передаю управление дочерней форме
this.Hide();
mainForm.ShowDialog();
this.Show();
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Очень странная ситуацияКогда запускаю проект в студии, выбираю файл в форме он отправляется и возвращает нужные мне данные
Собрал проект, всё хорошоЗапускаю андроид приложение и выводится такая ошибка
yii2-advanced, сохраняю и записываю картинку к записи в бд