Na przykład załóżmy, że jestem w formie 1, a następnie chcę:
- Otwórz formularz 2 (z przycisku w formularzu 1)
- Zamknij formularz 1
- Skoncentruj się na formularzu 2
Na przykład załóżmy, że jestem w formie 1, a następnie chcę:
Odpowiedzi:
Rozwiązanie Steve'a nie działa. Podczas wywoływania this.Close (), bieżący formularz jest usuwany razem z form2. Dlatego musisz to ukryć i ustawić zdarzenie form2.Closed, aby wywołać 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();
Czy mogę wiedzieć, jak działa to stwierdzenie? co to właściwie (s,args)
jest?
(s, args) => this.Close();
jest wyrażeniem lambda. Tworzy funkcję „na miejscu”, która jest wywoływana, gdy form2.Closed
zdarzenie jest uruchamiane. (s, args)
to tylko nazwy parametrów lambdy. Które dla obsługi zdarzeń są zwykle czymś w rodzaju (object sender, EventArgs e)
. Ponieważ Closed
podpis delegata wydarzenia opisuje ich typy, typy nie są podawane (ktoś w razie potrzeby skoryguje moje sformułowanie). // Ogólnie rzecz biorąc, jest to po prostu trudny sposób, aby nie musieć deklarować całej funkcji (obsługi zdarzenia) poza bieżącą, która obsługuje Form2.Closed
zdarzenie.
Spróbuj to zrobić ...
{
this.Hide();
Form1 sistema = new Form1();
sistema.ShowDialog();
this.Close();
}
W innych odpowiedziach opisano już wiele różnych sposobów. Jednak wielu z nich jest zaangażowanych ShowDialog()
lub form1
pozostaje otwartych, ale ukrytych. Moim zdaniem najlepszym i najbardziej intuicyjnym sposobem jest po prostu zamknięcie, form1
a następnie tworzenie form2
z zewnętrznego miejsca (tj. Nie z poziomu żadnej z tych form). W przypadku, gdy form1
został utworzony w Main
, form2
można go po prostu utworzyć za pomocą Application.Run
tak jak form1
wcześniej. Oto przykładowy scenariusz:
Chcę, aby użytkownik wprowadził swoje dane uwierzytelniające, abym mógł je w jakiś sposób uwierzytelnić. Następnie, jeśli uwierzytelnienie się powiedzie, chcę pokazać użytkownikowi główną aplikację. Aby to osiągnąć, używam dwóch formularzy: LogingForm
i MainForm
. LoginForm
Ma flagę, która określa, czy autoryzacja przebiegła pomyślnie, czy nie. Ta flaga jest następnie używana do podjęcia decyzji, czy utworzyć MainForm
instancję, czy nie. Żaden z tych formularzy nie musi wiedzieć o drugim i oba formularze można z wdziękiem otwierać i zamykać. Oto kod:
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
poprzednio) lub stan globalny, aby zdecydować, czy ponownie uruchomić formularz logowania, uruchomić inny formularz, a może zakończyć proces.
Problem tkwi w tej linii:
Application.Run(new Form1());
Który prawdopodobnie można znaleźć w pliku program.cs.
Ta linia wskazuje, że form1 ma obsługiwać pętlę komunikatów - innymi słowy form1 jest odpowiedzialny za kontynuowanie wykonywania aplikacji - aplikacja zostanie zamknięta po zamknięciu formularza form1.
Jest kilka sposobów, aby sobie z tym poradzić, ale wszystkie z nich w taki czy inny sposób nie zamkną formularza1.
(Chyba że zmienimy typ projektu na inny niż aplikacja Windows Forms)
Myślę, że najłatwiej w twojej sytuacji jest utworzenie 3 formularzy:
form1 - pozostanie niewidoczny i będzie działał jako menedżer, możesz go przypisać do obsługi ikony w zasobniku, jeśli chcesz.
form2 - będzie miał przycisk, którego kliknięcie zamknie formularz2 i otworzy formularz3
form3 - będzie pełnił rolę drugiego formularza, który trzeba otworzyć.
A oto przykładowy kod, aby to osiągnąć:
(dodałem również przykład zamykania aplikacji z 3. formularza)
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.
}
}
Uwaga: praca z panelami lub dynamiczne ładowanie elementów sterujących użytkownika jest bardziej akademickie i preferowane jako branżowe standardy produkcji - ale wydaje mi się, że po prostu próbujesz zrozumieć, jak to działa - w tym celu ten przykład jest lepszy.
A teraz, gdy zasady są już zrozumiane, wypróbujmy to tylko w dwóch formach:
Pierwsza forma przyjmie rolę menedżera, tak jak w poprzednim przykładzie, ale będzie również przedstawiać pierwszy ekran - więc nie zostanie zamknięty tylko ukryty.
Drugi formularz przejmie rolę pokazania kolejnego ekranu i po kliknięciu przycisku zamknie aplikację.
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();
}
}
Jeśli zmienisz poprzedni przykład - usuń formularz3 z projektu.
Powodzenia.
Nie byłeś konkretny, ale wygląda na to, że próbowałeś zrobić to, co robię w moich aplikacjach Win Forms: zacznij od formularza logowania, a następnie po pomyślnym zalogowaniu zamknij ten formularz i skup się na formularzu głównym. Oto jak to robię:
zrobić frmMain formularz startowy; tak wygląda mój Program.cs:
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new frmMain());
}
w moim frmLogin utwórz właściwość publiczną, która zostanie zainicjowana na false i ustawiona na true tylko wtedy, gdy nastąpi pomyślne logowanie:
public bool IsLoggedIn { get; set; }
mój frmMain wygląda następująco:
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;
}
Brak pomyślnego logowania? Zamknij aplikację. W przeciwnym razie kontynuuj z frmMain. Ponieważ jest to formularz startowy, po zamknięciu aplikacja kończy się.
użyj tego fragmentu kodu w swoim formularzu 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();
}
Mam to stąd
Jeśli masz dwa formularze: frm_form1 i frm_form2. Poniższy kod służy do otwierania frm_form2 i zamykania frm_form1. (Dla aplikacji formularzy systemu 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();
Zwykle robię to, aby przełączać się między formularzami.
Najpierw w pliku programu zachowuję ApplicationContext i dodaję metodę pomocniczą 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();
}
}
Następnie w dowolnym miejscu kodu wywołuję teraz metodę SwitchMainForm , aby łatwo przejść do nowego formularza.
// 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();
}
Ten kod może ci pomóc:
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();
Myślę, że to jest dużo łatwiejsze :)
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();
}
Załóżmy, że masz dwa formularze, pierwsza nazwa formularza to Form1, a druga nazwa formularza to Form2. Musisz przejść z Form1 do Form2 i wprowadzić kod tutaj. Napisz kod jak poniżej:
Na Form1 mam jeden przycisk o nazwie Button1 i po jego kliknięciu napisz poniższy kod:
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();
}
Mam nadzieję, że ten kod ci pomoże
this.Visible=false; this.Hide(); this.Close(); this.Dispose();
są zbędne. Nie potrzebujesz niczego więcej niż Close()
. Zamknięcie formularza usuwa go, ustawienie widoczności formularza jest tym samym, co ukrycie go, a ukrycie formularza jest bezcelowe, gdy nie będzie istnieć przed kolejnym zdarzeniem malowania.
Rozwiązałbym to, wykonując:
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
a potem this.Hide
? Dlaczego robisz to samo dwa razy?
Form1
i nic z tym nie robisz?