c # yeni bir form açıp mevcut formu kapat?


89

Örneğin, 1. formda olduğumu varsayın, sonra şunu istiyorum:

  1. Form 2'yi açın (form 1'deki bir düğmeden)
  2. Formu 1 kapat
  3. Form 2'ye odaklanın

18
Korkunç kullanılabilirlik. WinForms kullanıyorsanız, bir kap penceresi oluşturun ve bunun yerine panelleri değiştirin. Kullanıcılarınız sizi bunun için sevecek (ve yapmadığınız için sizden nefret edecek)
Claus Jørgensen

1
Claus'u dinleyin! Başarmaya çalıştığınız şey belki a) Sihirbaz benzeri sıralı bir dizi adımın winforms uygulaması veya b) Bir "veri girişi / gönderme" formundan sonra bir "sonuç" formu gösterme girişimidir. İster a) ister b) uygulamaya çalıştığınız UI davranışı yetersiz bir çözümdür.
Simen S

Clause ve Simen S çok teşekkürler. Yorumlarınız benim gibi yeni başlayanlara çok yardımcı oluyor. GUI ve kullanılabilirlik hakkında daha fazla öğretici okuyacağım. Bana yararlı olanları tavsiye edebilir misin?
tnhan07


Ayrıca , gerçek niyetiniz sadece bir giriş (veya benzeri) formu olup olmadığını [cevapları buradan] ( stackoverflow.com/questions/4759334/… ) kontrol edin .
ilias iliadis

Yanıtlar:


194

Steve'in çözümü işe yaramıyor. This.Close () çağrılırken, geçerli form form2 ile birlikte düzenlenir. Bu nedenle, bunu gizlemeniz ve this.Close () çağırmak için form2.Closed olayını ayarlamanız gerekir.

private void OnButton1Click(object sender, EventArgs e)
{
    this.Hide();
    var form2 = new Form2();
    form2.Closed += (s, args) => this.Close(); 
    form2.Show();
}

2
dot net'teki windows formlarında Kapalı olayı yoktur. Bana bunun FormClosed etkinliği olduğunu söyleyebilir misin
Anjali

2
İlk formu saklamak hala hafızasını tutmuyor mu? Bu kaynağı nasıl serbest bırakabiliriz?
user2635088

5
form2.Closed += (s, args) => this.Close();Bu ifadenin nasıl çalıştığını öğrenebilir miyim? tam olarak (s,args)nedir?
Yash Saraiya

1
(s, args) => this.Close();bir lambda ifadesidir. form2.ClosedOlay tetiklendiğinde çağrılan "yerinde" bir işlev oluşturur . (s, args)sadece lambda için parametrelerin isimleridir. Bir olay işleyicisi için hangisi genellikle buna benzer (object sender, EventArgs e). Çünkü Closedolay temsilci imzası onların türlerini açıklar, türleri (gerekirse Birisi ifadeler lütfen düzeltin) verilmemiştir. // Genel olarak, olayı işleyen geçerli işlevin dışında bir işlevin tamamını (olay işleyicisi) bildirmek zorunda kalmamanın zor bir yolu Form2.Closed.
KDecker

1
sadece ilk formu saklıyor ve yeni formu açıyor ancak ilk formu
kapatmıyor

25

Bunu yapmayı dene ...

{
    this.Hide();
    Form1 sistema = new Form1();
    sistema.ShowDialog();
    this.Close();
}

Işte burada. Bir Ana Formum var. ancak Giriş için küçük bir form kullanıyorum. Bu form, bu yöntemle Ana Formu çağırır. Tamam burada iyiyiz. Sorun, Ana Formun bir alt Form göstermesi ve alt formu kapatırken ... Ana Formu da Kapatmasıdır. Bu yüzden Nihique tarafından yayınlanan yöntemi kullanıyorum. Kod çok güzel çalışıyor! ...
MontDeska

bu kod benim için çalışıyor. VS 2015 kullanıyorum. Teşekkürler
IT Vlogs

22

Diğer cevaplar tarafından birçok farklı yol zaten açıklanmıştır. Ancak, birçoğu ya dahil oluyor ShowDialog()ya da form1açık ama gizli kalıyor. Bence en iyi ve en sezgisel yol, basitçe kapatmak form1ve sonra form2bir dış konumdan yaratmaktır (yani, bu iki formun içinden değil). İçinde form1yaratıldığı durumda Main, form2daha önce Application.Runolduğu gibi basitçe oluşturulabilir form1. Örnek bir senaryo:

Bir şekilde kimliğini doğrulayabilmem için kullanıcının kimlik bilgilerini girmesine ihtiyacım var. Daha sonra, kimlik doğrulama başarılı olursa, ana uygulamayı kullanıcıya göstermek istiyorum. Bunu başarmak için iki form kullanıyorum: LogingFormve MainForm. LoginFormKimlik doğrulama başarılı olup olmadığını belirler bir bayrağı vardır. Bu bayrak daha sonra MainFormörneğin oluşturulup oluşturulmayacağına karar vermek için kullanılır . Bu formların hiçbirinin diğeri hakkında bilgi sahibi olması gerekmez ve her iki form da zarif bir şekilde açılıp kapatılabilir. İşte bunun kodu:

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());
        }
    }
}

Bu, formları gizlemekten daha güzel bir numara. Uygulamadan çıkmak için gizli formlarımız olduğunda, sadece mevcut formu kapatmamız yeterli değildir. Application.Exit (0) vb.
Kullanmalıyız

Güzel ama bence sadece 2 form için uygun. Aralarında geçiş yapan birden çok form ne olacak?
Dr.MaF

Bu, OP'nin istediği gibi formları paralel veya üst üste değil sırayla çalıştırmakla sınırlıdır. Yine de bunun neden yalnızca 2 formla sınırlı olduğundan emin değilim. Dış kod, istenildiği kadar sırayla çok sayıda form üretmekte özgürdür. Bunlar arasında geçiş, dış kod tarafından da yapılabilir. loginForm.UserSuccessfullyAuthenticatedGiriş formunun yeniden çalıştırılıp çalıştırılmayacağına veya başka bir formun çalıştırılıp çalıştırılmayacağına veya belki süreci sonlandırıp sonlandırmayacağına karar vermek için ana formdaki bazı durumları ( önceki gibi ) veya belki genel durumu kontrol edebilir.
Manuzor

11

Bu satırdaki sorun var:

Application.Run(new Form1()); Muhtemelen program.cs dosyanızda bulunabilir.

Bu satır, form1'in mesaj döngüsünü idare edeceğini belirtir - başka bir deyişle, form1 uygulamanızı yürütmekten sorumludur - form1 kapatıldığında uygulama kapatılır.

Bunu halletmenin birkaç yolu var, ancak hepsi bir şekilde form1'i kapatmayacaktır.
(Proje türünü Windows form uygulaması dışında bir şeyle değiştirmedikçe)

Durumunuz için en kolay olanı 3 form oluşturmaktır:

  • form1 - görünmez kalacak ve bir yönetici olarak hareket edecek, isterseniz bir tepsi simgesini kullanması için atayabilirsiniz.

  • form2 - tıklandığında form2'yi kapatacak ve form3'ü açacak düğmeye sahip olacak

  • form3 - açılması gereken diğer formun rolüne sahip olacaktır.

Ve işte bunu başarmak için örnek bir kod:
(Uygulamayı 3. formdan kapatmak için bir örnek de ekledim)

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.
    }
}


Not: Panellerle çalışmak veya kullanıcı kontrollerini dinamik olarak yüklemek, endüstri üretim standartları olarak daha akademik ve tercih edilir - ama bana öyle geliyor ki, sadece işlerin nasıl çalıştığını anlamaya çalışıyorsunuz - bu amaçla bu örnek daha iyi.

Ve şimdi ilkeler anlaşıldığına göre, bunu sadece iki şekilde deneyelim:

  • İlk form, önceki örnekte olduğu gibi yönetici rolünü üstlenecek, ancak ilk ekranı da sunacak - böylece kapatılmayacak, sadece gizli kalacaktır.

  • İkinci form, bir sonraki ekranı gösterme rolünü üstlenecek ve bir düğmeye tıklayarak uygulamayı kapatacaktır.


    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();
        }
    }

Önceki örneği değiştirirseniz - form3'ü projeden silin.

İyi şanslar.


6

Spesifik değildiniz, ancak Win Forms uygulamalarımda yaptığım şeyi yapmaya çalıştığınız anlaşılıyor: Bir Giriş formu ile başlayın, ardından başarılı bir şekilde giriş yaptıktan sonra bu formu kapatın ve bir Ana forma odaklanın. İşte bunu nasıl yapıyorum:

  1. make frmMain başlangıç ​​formu; Program.cs'm şöyle görünüyor:

    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new frmMain());
    }
    
  2. frmLogin'imde, false olarak başlatılan ve yalnızca başarılı bir oturum açma gerçekleşirse true olarak ayarlanan bir genel özellik oluşturun:

    public bool IsLoggedIn { get; set; }
    
  3. my frmMain şöyle görünüyor:

    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;
        }
    

Başarılı giriş yok mu? Uygulamadan çıkın. Aksi takdirde frmMain ile devam edin. Başlangıç ​​formu olduğu için kapandığında uygulama sona erer.


3

bu kod parçacığını formunuzda kullanın1.

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();
}

Bunu buradan aldım


Yalnızca bağlantı yanıtlarının cesaretinin kırıldığını, SO yanıtlarının bir çözüm arayışının son noktası olması gerektiğini unutmayın (zamanla bayatlama eğiliminde olan referansların başka bir mola yerine). Lütfen bağlantıyı referans alarak buraya bağımsız bir özet eklemeyi düşünün.
kleopatra

2

İki formunuz varsa: frm_form1 ve frm_form2. Aşağıdaki kod frm_form2'yi açmak ve frm_form1'i kapatmak için kullanılır. (Windows form uygulaması için)

        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();

1

Bunu genellikle formlar arasında geçiş yapmak için yapıyorum.

İlk olarak, Program dosyasında ApplicationContext'i tutuyorum ve yardımcı bir SwitchMainForm yöntemi ekliyorum .

        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();
    }


}

Daha sonra kodun herhangi bir yerinde şimdi kolayca yeni forma geçmek için SwitchMainForm yöntemini çağırıyorum .

// switch to some other form
var otherForm = new MyForm();
Program.SwitchMainForm(otherForm);

0
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
}

Çalışmayacak. Bir sonraki formu göstermeden önce saklanmanın bir anlamı yok. Aynı anda yürütülecek ve program sonlandırılacaktır.
Ahmet Karabulut

0
//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();
}


0
                     this.Visible = false;
                        //or                         // will make LOgin Form invisivble
                        //this.Enabled = false;
                         //  or
                       // this.Hide(); 



                        Form1 form1 = new Form1();
                        form1.ShowDialog();

                        this.Dispose();

1
Bu cevap bu tartışmaya ne ekler? Diğer 9 cevapta bulunan herhangi bir açıklama bilgisi eklenmeden yeniden ifade edilmektedir.
Edward

0

Bunun çok daha kolay olduğunu düşünüyorum :)

    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();

    }

Bu çözüm, bu sorunun cevabı değildir. Çözümünüz mevcut formu kapatmayacak, bu, mevcut formun hala işlemde olduğu anlamına gelir.
Ahmet Karabulut

-1

İki Formunuz olduğunu varsayalım, İlk Form Adı Form1 ve ikinci form adı Form2. Form1'den Form2'ye atlamanız gerekiyor, kodu buraya girin. Aşağıdaki gibi kod yazın:

Form1'de Button1 adında bir düğme var ve tıklama seçeneğinde aşağıdaki kodu yazın:

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();
}

Umarım bu kod size yardımcı olur


Bu dört yöntem: this.Visible=false; this.Hide(); this.Close(); this.Dispose();gereksizdir. Daha fazlasına ihtiyacınız yok Close(). Bir formun kapatılması onu ortadan kaldırır, formun görünürlüğünü ayarlamak onu gizlemekle aynıdır ve bir formu gizlemek, bir sonraki boyama olayından önce var olmayacaksa anlamsızdır.
Servy

-3

Bunu yaparak çözerdim:

private void button1_Click(object sender, EventArgs e)
{
    Form2 m = new Form2();
    m.Show();
    Form1 f = new Form1();
    this.Visible = false;
    this.Hide();
}

3
this.Visible = falseve sonra this.Hide? Neden aynı şeyi iki kez yapıyorsun?
Neolisk

8
Ayrıca, neden yeni bir tane yaratıyorsun Form1ve onunla hiçbir şey yapmıyorsun?
Servy
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.