Por exemplo, suponha que estou no formulário 1 e então quero:
- Abra o formulário 2 (a partir de um botão no formulário 1)
- Fechar formulário 1
- Foco no formulário 2
Por exemplo, suponha que estou no formulário 1 e então quero:
Respostas:
A solução de Steve não funciona. Ao chamar this.Close (), o formulário atual é descartado junto com o form2. Portanto, você precisa ocultá-lo e definir o evento form2.Closed para chamar 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();
Posso saber como funciona esta declaração? o que exatamente (s,args)
é?
(s, args) => this.Close();
é uma expressão lambda. Ele cria uma função "no local" que é chamada quando o form2.Closed
evento é disparado. (s, args)
são apenas nomes para os parâmetros do lambda. Que para um manipulador de eventos geralmente são algo parecido (object sender, EventArgs e)
. Como a Closed
assinatura do delegado do evento descreve seus tipos, os tipos não são fornecidos (Alguém, por favor, corrija minhas palavras, se necessário). // No geral, é apenas uma maneira complicada de não ter que declarar uma função inteira (manipulador de eventos) fora da função atual que manipula o Form2.Closed
evento.
Tente fazer isso ...
{
this.Hide();
Form1 sistema = new Form1();
sistema.ShowDialog();
this.Close();
}
Muitas maneiras diferentes já foram descritas pelas outras respostas. No entanto, muitos deles estão envolvidos ShowDialog()
ou form1
permanecem abertos, mas ocultos. A melhor e mais intuitiva forma, em minha opinião, é simplesmente fechar form1
e criar form2
de um local externo (ou seja, não de dentro de nenhum desses formulários). No caso em que form1
foi criado em Main
, form2
pode simplesmente ser criado usando Application.Run
como form1
antes. Aqui está um exemplo de cenário:
Preciso que o usuário insira suas credenciais para que eu possa autenticá-lo de alguma forma. Depois, se a autenticação for bem-sucedida, quero mostrar o aplicativo principal ao usuário. Para fazer isso, estou usando dois formulários: LogingForm
e MainForm
. O LoginForm
possui um sinalizador que determina se a autenticação foi bem-sucedida ou não. Este sinalizador é então usado para decidir se deve criar a MainForm
instância ou não. Nenhum desses formulários precisa saber sobre o outro e ambos os formulários podem ser abertos e fechados normalmente. Aqui está o código para isso:
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
antes) ou talvez o estado global para decidir se deve executar novamente o formulário de login, ou executar outro formulário, ou talvez encerrar o processo.
O problema começa com essa linha:
Application.Run(new Form1());
Que provavelmente pode ser encontrado em seu arquivo program.cs.
Esta linha indica que form1 deve tratar o loop de mensagens - em outras palavras, form1 é responsável por continuar executando sua aplicação - a aplicação será fechada quando form1 for fechado.
Existem várias maneiras de lidar com isso, mas todas elas de uma forma ou de outra não fecharão o form1.
(A menos que alteremos o tipo de projeto para algo diferente do aplicativo de formulários do Windows)
O que eu acho mais fácil para sua situação é criar 3 formulários:
form1 - permanecerá invisível e atuará como um gerente, você pode atribuí-lo para lidar com um ícone da bandeja se desejar.
form2 - terá o botão, que ao ser clicado fecha o form2 e abre o form3
form3 - terá a função do outro formulário que precisa ser aberto.
E aqui está um código de amostra para fazer isso:
(também adicionei um exemplo para fechar o aplicativo do terceiro formulário)
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.
}
}
Nota: trabalhar com painéis ou carregar controles do usuário dinamicamente é mais acadêmico e preferível como padrões de produção da indústria - mas me parece que você está apenas tentando raciocinar sobre como as coisas funcionam - para esse propósito, este exemplo é melhor.
E agora que os princípios foram compreendidos, vamos tentar com apenas duas formas:
O primeiro formulário assumirá a função de gerente, assim como no exemplo anterior, mas também apresentará a primeira tela - portanto, não será fechada, apenas oculta.
O segundo formulário terá a função de mostrar a próxima tela e ao clicar em um botão fechará o aplicativo.
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();
}
}
Se você alterar o exemplo anterior - exclua o form3 do projeto.
Boa sorte.
Você não foi específico, mas parece que você estava tentando fazer o que eu faço nos meus aplicativos Win Forms: comece com um formulário de Login, depois de um login bem-sucedido, feche esse formulário e coloque o foco em um formulário Principal. É assim que eu faço:
tornar frmMain o formulário de inicialização; é assim que meu Program.cs se parece:
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new frmMain());
}
em meu frmLogin, crie uma propriedade pública que seja inicializada como falsa e definida como verdadeira apenas se ocorrer um login bem-sucedido:
public bool IsLoggedIn { get; set; }
meu frmMain se parece com isto:
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;
}
Sem sucesso de login? Saia do aplicativo. Caso contrário, continue com frmMain. Por ser o formulário de inicialização, quando fecha, o aplicativo termina.
use este trecho de código em seu form1.
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();
}
Eu peguei isso daqui
Se você tiver dois formulários: frm_form1 e frm_form2. O código a seguir é usado para abrir frm_form2 e fechar frm_form1. (Para aplicativos de formulário do 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();
Normalmente faço isso para alternar entre os formulários.
Em primeiro lugar, no arquivo de programa mantenho o ApplicationContext e adiciono um método auxiliar 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();
}
}
Em seguida, em qualquer lugar no código agora chamo o método SwitchMainForm para alternar facilmente para o novo formulário.
// 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();
}
Este código pode ajudá-lo:
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();
Acho que é muito mais fácil :)
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();
}
Suponha que você tenha dois Formulários, o nome do primeiro formulário é Form1 e o segundo nome do formulário é Form2.You tem que pular do Form1 para o Form2 e inserir o código aqui. Escreva o código como o seguinte:
No Form1, tenho um botão chamado Button1 e, na opção de clique, escrevo o código abaixo:
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();
}
Espero que este código ajude você
this.Visible=false; this.Hide(); this.Close(); this.Dispose();
são redundantes. Você não precisa de nada mais do que Close()
. Fechar um formulário descarta-o, definir a visibilidade do formulário é o mesmo que ocultá-lo, e ocultar um formulário é inútil quando ele não existirá antes do próximo evento de pintura.
Eu iria resolver isso fazendo:
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
e então this.Hide
? Por que fazer a mesma coisa duas vezes?
Form1
e não fazendo nada com ele?