Ad esempio, supponiamo che io sia nel modulo 1, quindi voglio:
- Apri modulo 2 (da un pulsante nel modulo 1)
- Chiudi modulo 1
- Concentrati sul modulo 2
Ad esempio, supponiamo che io sia nel modulo 1, quindi voglio:
Risposte:
La soluzione di Steve non funziona. Quando si chiama this.Close (), il form corrente viene eliminato insieme a form2. Pertanto è necessario nasconderlo e impostare l'evento form2.Closed per chiamare 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 sapere come funziona questa affermazione? che cos'è esattamente (s,args)
?
(s, args) => this.Close();
è un'espressione lambda. Crea una funzione "sul posto" che viene chiamata quando form2.Closed
viene generato l' evento. (s, args)
sono solo nomi per i parametri di lambda. Che per un gestore di eventi di solito sono qualcosa di simile (object sender, EventArgs e)
. Poiché la Closed
firma del delegato dell'evento descrive i loro tipi, i tipi non vengono forniti (qualcuno corregga la mia formulazione se necessario). // Nel complesso è solo un modo complicato per non dover dichiarare un'intera funzione (gestore di eventi) al di fuori di quella corrente che gestisce l' Form2.Closed
evento.
Prova a farlo ...
{
this.Hide();
Form1 sistema = new Form1();
sistema.ShowDialog();
this.Close();
}
Molti modi diversi sono già stati descritti dalle altre risposte. Tuttavia, molti di loro sono coinvolti ShowDialog()
o form1
rimangono aperti ma nascosti. Il modo migliore e più intuitivo secondo me è semplicemente chiudere form1
e quindi creare form2
da una posizione esterna (cioè non dall'interno di nessuna di queste forme). Nel caso in cui è form1
stato creato in Main
, form2
può essere semplicemente creato utilizzando Application.Run
proprio comeform1
prima. Ecco uno scenario di esempio:
Ho bisogno che l'utente inserisca le proprie credenziali per poterle autenticare in qualche modo. Successivamente, se l'autenticazione ha avuto successo, voglio mostrare l'applicazione principale all'utente. Per fare ciò, sto usando due forme: LogingForm
e MainForm
. L' LoginForm
ha una bandiera che determina se l'autenticazione ha avuto successo o meno. Questo flag viene quindi utilizzato per decidere se creare MainForm
o meno l' istanza. Nessuno di questi moduli deve conoscere l'altro ed entrambi i moduli possono essere aperti e chiusi con grazia. Ecco il codice per questo:
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
prima) o forse uno stato globale per decidere se eseguire nuovamente il modulo di accesso o eseguire un altro modulo o forse terminare il processo.
Il problema inizia con quella linea:
Application.Run(new Form1());
Che probabilmente si trova nel file program.cs.
Questa riga indica che form1 deve gestire il ciclo dei messaggi - in altre parole form1 è responsabile di continuare a eseguire l'applicazione - l'applicazione verrà chiusa quando form1 viene chiuso.
Ci sono diversi modi per gestire questo problema, ma tutti in un modo o nell'altro non chiuderanno form1.
(A meno che non cambiamo il tipo di progetto in qualcosa di diverso dall'applicazione Windows Form)
Quello che penso sia più facile per la tua situazione è creare 3 moduli:
form1 - rimarrà invisibile e agirà come un manager, puoi assegnarlo a gestire un'icona nel vassoio se lo desideri.
form2 - avrà il pulsante, che se cliccato chiuderà form2 e aprirà form3
form3 - avrà il ruolo dell'altro modulo che deve essere aperto.
Ed ecco un codice di esempio per farlo:
(Ho anche aggiunto un esempio per chiudere l'app dal 3 ° modulo)
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: lavorare con i pannelli o caricare dinamicamente i controlli utente è più accademico e preferibile come standard di produzione del settore - ma mi sembra che tu stia solo cercando di ragionare su come funzionano le cose - a tal fine questo esempio è migliore.
E ora che i principi sono compresi proviamolo con due sole forme:
Il primo modulo assumerà il ruolo di manager proprio come nell'esempio precedente ma presenterà anche la prima schermata, quindi non verrà chiuso ma solo nascosto.
Il secondo modulo avrà il ruolo di mostrare la schermata successiva e facendo clic su un pulsante si chiuderà l'applicazione.
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 modifichi l'esempio precedente, elimina form3 dal progetto.
In bocca al lupo.
Non eri specifico, ma sembra che tu stia cercando di fare quello che faccio io nelle mie app Win Forms: inizia con un modulo di accesso, quindi dopo aver effettuato correttamente l'accesso, chiudi quel modulo e concentrati su un modulo principale. Ecco come lo faccio:
rendere frmMain il form di avvio; questo è l'aspetto del mio Program.cs:
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new frmMain());
}
nel mio frmLogin, crea una proprietà pubblica che viene inizializzata su false e impostata su true solo se si verifica un accesso riuscito:
public bool IsLoggedIn { get; set; }
my frmMain ha questo aspetto:
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;
}
Nessun accesso riuscito? Esci dall'applicazione. Altrimenti, continuare con frmMain. Poiché è il modulo di avvio, quando si chiude, l'applicazione termina.
usa questo snippet di codice nel tuo modulo 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();
}
L'ho preso da qui
Se hai due moduli: frm_form1 e frm_form2. Il codice seguente viene utilizzato per aprire frm_form2 e chiudere frm_form1. (Per l'applicazione Windows Form)
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();
Di solito lo faccio per passare da una forma all'altra.
In primo luogo, nel file di programma mantengo ApplicationContext e aggiungo un metodo SwitchMainForm di supporto .
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();
}
}
Quindi in qualsiasi punto del codice ora chiamo il metodo SwitchMainForm per passare facilmente al nuovo modulo.
// 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();
}
Questo codice può aiutarti:
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();
Penso che sia molto più facile :)
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();
}
Supponiamo di avere due form, il nome del primo modulo è Form1 e il nome del secondo modulo è Form2. Devi passare da Form1 a Form2 inserisci il codice qui Scrivi il codice come segue:
Su Form1 ho un pulsante chiamato Button1 e sulla sua opzione di clic scrivi sotto il codice:
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();
}
Spero che questo codice ti aiuti
this.Visible=false; this.Hide(); this.Close(); this.Dispose();
sono ridondanti. Non hai bisogno di nient'altro che Close()
. La chiusura di un modulo lo elimina, impostare la visibilità del modulo equivale a nasconderlo e nascondere un modulo è inutile quando non esisterà prima del prossimo evento di disegno.
Lo risolverei facendo:
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 poi this.Hide
? Perché fare la stessa cosa due volte?
Form1
e non ne fai nulla?