Например, предположим, что я нахожусь в форме 1, тогда я хочу:
- Открыть форму 2 (с кнопки в форме 1)
- Закрыть форму 1
- Сосредоточьтесь на форме 2
Например, предположим, что я нахожусь в форме 1, тогда я хочу:
Ответы:
Решение Стива не работает. При вызове this.Close () текущая форма удаляется вместе с form2. Поэтому вам нужно скрыть его и установить событие form2.Closed для вызова this.Close ().
private void OnButton1Click(object sender, EventArgs e)
{
this.Hide();
var form2 = new Form2();
form2.Closed += (s, args) => this.Close();
form2.Show();
}
form2.Closed += (s, args) => this.Close();
Могу я узнать, как работает это заявление? что именно (s,args)
?
(s, args) => this.Close();
является лямбда-выражением. Он создает функцию «на месте», которая вызывается при form2.Closed
срабатывании события. (s, args)
это просто имена параметров лямбда. Которые для обработчика событий обычно выглядят примерно так (object sender, EventArgs e)
. Поскольку Closed
подпись делегата события описывает их типы, типы не указаны (кто-нибудь, пожалуйста, исправьте мою формулировку, если необходимо). // В целом, это просто хитрый способ не объявлять целую функцию (обработчик событий) за пределами текущей, которая обрабатывает Form2.Closed
событие.
Попробуй сделать это ...
{
this.Hide();
Form1 sistema = new Form1();
sistema.ShowDialog();
this.Close();
}
В других ответах уже описано много разных способов. Однако многие из них либо участвуют, ShowDialog()
либо form1
остаются открытыми, но скрытыми. На мой взгляд, лучший и самый интуитивно понятный способ - просто закрыть, form1
а затем создать form2
извне (т.е. не изнутри любой из этих форм). В случае, если form1
был создан в Main
, form2
может быть просто создан, Application.Run
как и form1
раньше. Вот пример сценария:
Мне нужно, чтобы пользователь ввел свои учетные данные, чтобы я как-то их аутентифицировал. Впоследствии, если аутентификация прошла успешно, я хочу показать пользователю главное приложение. Для этого я использую две формы: LogingForm
и MainForm
. У LoginForm
него есть флаг, который определяет, была ли аутентификация успешной или нет. Затем этот флаг используется, чтобы решить, создавать ли MainForm
экземпляр или нет. Ни одна из этих форм не должна знать о другой, и обе формы можно открывать и закрывать изящно. Вот код для этого:
class LoginForm : Form
{
public bool UserSuccessfullyAuthenticated { get; private set; }
void LoginButton_Click(object s, EventArgs e)
{
if(AuthenticateUser(/* ... */))
{
UserSuccessfullyAuthenticated = true;
Close();
}
}
}
static class Program
{
[STAThread]
static void Main()
{
LoginForm loginForm = new LoginForm();
Application.Run(loginForm);
if(loginForm.UserSuccessfullyAuthenticated)
{
// MainForm is defined elsewhere
Application.Run(new MainForm());
}
}
}
loginForm.UserSuccessfullyAuthenticated
раньше) или, возможно, глобальное состояние, чтобы решить, следует ли повторно запустить форму входа в систему или запустить другую форму, или, возможно, завершить процесс.
Проблема заключается в этой строке:
Application.Run(new Form1());
Что, вероятно, можно найти в вашем файле program.cs.
Эта строка указывает, что form1 должен обрабатывать цикл сообщений - другими словами form1 отвечает за выполнение вашего приложения - приложение будет закрыто при закрытии form1.
Есть несколько способов справиться с этим, но все они так или иначе не закрывают form1.
(Если мы не изменим тип проекта на что-то другое, кроме приложения Windows Forms)
Я считаю, что проще всего в вашей ситуации создать 3 формы:
form1 - останется невидимым и будет действовать как менеджер, вы можете назначить его для обработки значка в трее, если хотите.
form2 - будет кнопка, при нажатии на которую закроется form2 и откроется form3
form3 - будет играть роль другой формы, которую нужно открыть.
И вот пример кода для этого:
(я также добавил пример, чтобы закрыть приложение из третьей формы)
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1()); //set the only message pump to form1.
}
}
public partial class Form1 : Form
{
public static Form1 Form1Instance;
public Form1()
{
//Everyone eveywhere in the app should know me as Form1.Form1Instance
Form1Instance = this;
//Make sure I am kept hidden
WindowState = FormWindowState.Minimized;
ShowInTaskbar = false;
Visible = false;
InitializeComponent();
//Open a managed form - the one the user sees..
var form2 = new Form2();
form2.Show();
}
}
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
var form3 = new Form3(); //create an instance of form 3
Hide(); //hide me (form2)
form3.Show(); //show form3
Close(); //close me (form2), since form1 is the message loop - no problem.
}
}
public partial class Form3 : Form
{
public Form3()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form1.Form1Instance.Close(); //the user want to exit the app - let's close form1.
}
}
Примечание: работа с панелями или динамическая загрузка пользовательских элементов управления более академична и предпочтительнее, чем промышленные стандарты производства - но мне кажется, вы просто пытаетесь рассуждать о том, как все работает - для этой цели этот пример лучше.
А теперь, когда принципы понятны, давайте попробуем использовать всего две формы:
Первая форма возьмет на себя роль менеджера, как и в предыдущем примере, но также будет представлять первый экран - поэтому он не будет закрыт, просто скрыт.
Вторая форма будет отображать следующий экран, а нажатие кнопки закроет приложение.
public partial class Form1 : Form
{
public static Form1 Form1Instance;
public Form1()
{
//Everyone eveywhere in the app show know me as Form1.Form1Instance
Form1Instance = this;
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//Make sure I am kept hidden
WindowState = FormWindowState.Minimized;
ShowInTaskbar = false;
Visible = false;
//Open another form
var form2 = new Form2
{
//since we open it from a minimezed window - it will not be focused unless we put it as TopMost.
TopMost = true
};
form2.Show();
//now that that it is topmost and shown - we want to set its behavior to be normal window again.
form2.TopMost = false;
}
}
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form1.Form1Instance.Close();
}
}
Если вы измените предыдущий пример - удалите form3 из проекта.
Удачи.
Вы не уточнили, но похоже, что вы пытались делать то, что я делаю в своих приложениях Win Forms: начните с формы входа, затем, после успешного входа в систему, закройте эту форму и переключите фокус на главную форму. Вот как я это делаю:
сделать frmMain стартовой формой; вот как выглядит мой Program.cs:
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new frmMain());
}
в моем frmLogin создайте общедоступное свойство, которое инициализируется значением false и устанавливается в значение true только в случае успешного входа в систему:
public bool IsLoggedIn { get; set; }
мой frmMain выглядит так:
private void frmMain_Load(object sender, EventArgs e)
{
frmLogin frm = new frmLogin();
frm.IsLoggedIn = false;
frm.ShowDialog();
if (!frm.IsLoggedIn)
{
this.Close();
Application.Exit();
return;
}
Нет успешного входа? Выйти из приложения. В противном случае продолжайте с frmMain. Поскольку это стартовая форма, когда она закрывается, приложение заканчивается.
используйте этот фрагмент кода в своей форме1.
public static void ThreadProc()
{
Application.Run(new Form());
}
private void button1_Click(object sender, EventArgs e)
{
System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(ThreadProc));
t.Start();
this.Close();
}
Я получил это отсюда
Если у вас две формы: frm_form1 и frm_form2. Следующий код используется для открытия frm_form2 и закрытия frm_form1. (Для приложения формы Windows)
this.Hide();//Hide the 'current' form, i.e frm_form1
//show another form ( frm_form2 )
frm_form2 frm = new frm_form2();
frm.ShowDialog();
//Close the form.(frm_form1)
this.Close();
Обычно я делаю это, чтобы переключаться между формами.
Во-первых, в файле Program я сохраняю ApplicationContext и добавляю вспомогательный метод SwitchMainForm .
static class Program
{
public static ApplicationContext AppContext { get; set; }
static void Main(string[] args)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
//Save app context
Program.AppContext = new ApplicationContext(new LoginForm());
Application.Run(AppContext);
}
//helper method to switch forms
public static void SwitchMainForm(Form newForm)
{
var oldMainForm = AppContext.MainForm;
AppContext.MainForm = newForm;
oldMainForm?.Close();
newForm.Show();
}
}
Затем в любом месте кода я вызываю метод SwitchMainForm, чтобы легко переключиться на новую форму.
// switch to some other form
var otherForm = new MyForm();
Program.SwitchMainForm(otherForm);
private void buttonNextForm(object sender, EventArgs e)
{
NextForm nf = new NextForm();//Object of the form that you want to open
this.hide();//Hide cirrent form.
nf.ShowModel();//Display the next form window
this.Close();//While closing the NextForm, control will come again and will close this form as well
}
//if Form1 is old form and Form2 is the current form which we want to open, then
{
Form2 f2 = new Form1();
this.Hide();// To hide old form i.e Form1
f2.Show();
}
Этот код может помочь вам:
Master frm = new Master();
this.Hide();
frm.ShowDialog();
this.Close();
this.Visible = false;
//or // will make LOgin Form invisivble
//this.Enabled = false;
// or
// this.Hide();
Form1 form1 = new Form1();
form1.ShowDialog();
this.Dispose();
Думаю, это намного проще :)
private void btnLogin_Click(object sender, EventArgs e)
{
//this.Hide();
//var mm = new MainMenu();
//mm.FormClosed += (s, args) => this.Close();
//mm.Show();
this.Hide();
MainMenu mm = new MainMenu();
mm.Show();
}
Предположим, у вас есть две формы, первое имя формы - Form1, а второе имя формы - Form2. Вам нужно перейти от Form1 к Form2, введите здесь код. Напишите такой код:
В Form1 у меня есть одна кнопка с именем Button1, и при ее нажатии напишите ниже код:
protected void Button1_Click(Object sender,EventArgs e)
{
Form frm=new Form2();// I have created object of Form2
frm.Show();
this.Visible=false;
this.Hide();
this.Close();
this.Dispose();
}
Надеюсь, этот код поможет вам
this.Visible=false; this.Hide(); this.Close(); this.Dispose();
избыточны. Больше ничего не нужно Close()
. Закрытие формы избавляется от нее, установка видимости формы такая же, как ее скрытие, а скрытие формы бессмысленно, если она не будет существовать до следующего события рисования.
Я бы решил это, выполнив:
private void button1_Click(object sender, EventArgs e)
{
Form2 m = new Form2();
m.Show();
Form1 f = new Form1();
this.Visible = false;
this.Hide();
}
this.Visible = false
а потом this.Hide
? Зачем делать одно и то же дважды?
Form1
и ничего не делаете с ним?