Страницы

Поиск по вопросам

суббота, 20 апреля 2019 г.

Закрыть Form1, открыть Form2

Да-да-да, понимаю, тема "заезжая", но сколько я не рыл, ни где толком не объясняется почему все скрывают/показывают форму так:
Form2 frm = new Form2(); this.Hide(); frm.Show();
Таким способом, активная форма не закрывается, а скрывается, правильно?
Как правильно закрыть Form1 и открыть Form2?


Ответ

В проекте WinForms есть два вида форм - главная и дочерние. Разница между ними в том, что главная форма по сути и является приложением, поэтому при ее закрытии происходит выход из приложения.
Одним из решений является скрытие главной формы, вместо закрытия. Этот вариант уже написан в вопросе. Он обычно применяется, когда главная форма так или иначе используется в дальнейшем.
Если первая форма в дальнейшем не используется, то можно использовать 2 варианта:
1. Правим Program.cs
По умолчанию содержимое файла Program.cs выглядит так:
using System; using System.Windows.Forms;
namespace WindowsFormsApplication4 { static class Program { ///

/// The main entry point for the application. /// [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } } }
Как вы можете заметить, Form1 запускается как приложение и, при завершении работы формы, произойдет выход из Main и приложения.
Чтобы этого не произошло, можно прописать последовательность запуска форм:
Application.Run(new Form1()); Application.Run(new Form2()); Application.Run(new Form3());
Тогда при закрытии первой формы, будет вызвана вторая и так до последней.
Недостаток - сложно передавать данные между формами. Да можно определить поля в классе Program, конструкторы с параметрами в формах и передавать данные через эти поля и параметры конструкторов, но что делать если нужно вернуться в одну из предыдущих форм? Пилить сложную логику переходов в Main - не сама лучшая идея, мягко говоря.
2. Переходим от форм к контролам
В WinForms есть замечательный класс UserControl. Это фактически пустой контрол, который вы можете наполнить любым содержимым как и форму.
После того, как набор таких контролов подготовлен, вам остается только разместить их на форме с параметром Dock = DockStyle.Fill и управляя значением свойства Conrol.Visible, показывать тот контрол, который вам нужен в данный момент. Если не хотите держать контрол в памяти, ни кто не мешает просто создавать его в нужный момент и отображать, а после использования и переключения на новый контрол, отписаться от событий, вызвать Dispose(), удалить все ссылки и отдать его на растерзание сборщику мусора. Только выигрыш от этого невелик, особенно если вдруг надумаете снова его показать.

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

Ещё можно не передавать форму в Application.Run и запустить его без параметров. Тогда даже закрытие всех форм не приведёт к закрытию приложения. Чтобы выйти окончательно необходимо будет вызвать Application.Exit – Lunar Whisper
Тоже хороший вариант, если необходимо использовать разные формы в процессе работы.

Комментариев нет:

Отправить комментарий