c # mở một biểu mẫu mới rồi đóng biểu mẫu hiện tại?


89

Ví dụ: Giả sử rằng tôi đang ở dạng 1 thì tôi muốn:

  1. Mở biểu mẫu 2 (từ một nút trong biểu mẫu 1)
  2. Đóng biểu mẫu 1
  3. Tập trung vào dạng 2

18
Khả năng sử dụng khủng khiếp. Nếu bạn đang sử dụng WinForms, thì chỉ cần tạo một cửa sổ vùng chứa và thay thế các bảng điều khiển. Người dùng của bạn sẽ yêu em cho nó (và ghét anh vì đã không làm việc đó)
Claus Jørgensen

1
Hãy nghe Claus! Những gì bạn đang cố gắng đạt được có lẽ là a) Việc triển khai một chuỗi các bước tuần tự giống như thuật sĩ hoặc b) Cố gắng hiển thị biểu mẫu "kết quả" sau biểu mẫu "nhập / gửi dữ liệu". Bất kể đó là a) hay b) hành vi UI mà bạn đang cố gắng thực hiện đều là một giải pháp không tối ưu.
Simen S

Cảm ơn Khoản và Simen S rất nhiều. Nhận xét của bạn rất hữu ích cho một người mới bắt đầu như tôi. Tôi sẽ đọc thêm các hướng dẫn về GUI và khả năng sử dụng. Bạn có thể giới thiệu cho tôi một số cái hữu ích?
tnhan07


Cũng kiểm tra [câu trả lời tại đây] ( stackoverflow.com/questions/4759334/… ), nếu ý định thực sự của bạn chỉ là có một biểu mẫu đăng nhập (hoặc giống nhau).
ilias iliadis

Câu trả lời:


194

Giải pháp của Steve không hoạt động. Khi gọi this.Close (), form hiện tại được xử lý cùng với form2. Do đó bạn cần ẩn nó đi và đặt sự kiện form2.Closed để gọi this.Close ().

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

2
không có sự kiện Đóng trong các biểu mẫu cửa sổ trong dot net. Bạn có thể cho tôi biết là nó FormClosed sự kiện
Anjali

2
Không phải ẩn hình thức đầu tiên vẫn giữ cho nó bộ nhớ? Làm thế nào chúng ta có thể giải phóng tài nguyên đó?
user2635088

5
form2.Closed += (s, args) => this.Close();Tôi có thể biết câu lệnh này hoạt động như thế nào không? chính xác (s,args)là gì?
Yash Saraiya

1
(s, args) => this.Close();là một biểu thức lambda. Nó tạo ra một hàm "tại chỗ" được gọi khi form2.Closedsự kiện được kích hoạt. (s, args)chỉ là tên cho các tham số của lambda. Đối với một trình xử lý sự kiện thường là một cái gì đó giống như (object sender, EventArgs e). Bởi vì Closedchữ ký đại biểu sự kiện mô tả các loại của họ, các loại không được đưa ra (Ai đó vui lòng sửa từ ngữ của tôi nếu cần). // Nhìn chung, nó chỉ là một cách phức tạp để không phải khai báo toàn bộ một hàm (trình xử lý sự kiện) bên ngoài hàm xử lý sự kiện hiện tại Form2.Closed.
KDecker

1
nó chỉ ẩn hình thức đầu tiên và mở hình thức mới nhưng không đóng hình thức đầu tiên
Uddyan Semwal

25

Cố gắng làm điều này ...

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

Đây là điều. Tôi có một Biểu mẫu chính. nhưng tôi sử dụng một biểu mẫu nhỏ để đăng nhập. Biểu mẫu này gọi Biểu mẫu chính với phương thức này. Ok chúng tôi ở đây tốt. Vấn đề là khi Biểu mẫu chính hiển thị một Biểu mẫu con và khi đóng biểu mẫu con ... nó cũng sẽ Đóng Biểu mẫu chính. Vì vậy, Vì tôi đang sử dụng phương pháp được xuất bản bởi Nihique. Mã đã hoạt động rất tốt! ...
MontDeska

mã này đang làm việc cho tôi. tôi đang sử dụng VS 2015. Cảm ơn
IT Vlogs

21

Nhiều cách khác nhau đã được mô tả bởi các câu trả lời khác. Tuy nhiên, nhiều người trong số họ có liên quan ShowDialog()hoặc form1vẫn mở nhưng ẩn. Cách tốt nhất và trực quan nhất theo ý kiến ​​của tôi là chỉ cần đóng form1và sau đó tạo form2từ một vị trí bên ngoài (tức là không phải từ bên trong một trong hai hình thức đó). Trong trường hợp form1được tạo trong Main, form2chỉ có thể được tạo bằng cách sử dụng Application.Rungiống như form1trước đây. Đây là một tình huống ví dụ:

Tôi cần người dùng nhập thông tin đăng nhập của họ để tôi xác thực bằng cách nào đó. Sau đó, nếu xác thực thành công, tôi muốn hiển thị ứng dụng chính cho người dùng. Để thực hiện điều này, tôi đang sử dụng hai biểu mẫu: LogingFormMainForm. Có LoginFormmột cờ xác định xem xác thực có thành công hay không. Cờ này sau đó được sử dụng để quyết định có tạo MainFormcá thể hay không. Cả hai biểu mẫu này không cần biết về biểu mẫu kia và cả hai biểu mẫu đều có thể được mở và đóng một cách duyên dáng. Đây là mã cho việc này:

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

Đây là một thủ thuật hay hơn là ẩn hình thức. Khi chúng ta có các biểu mẫu ẩn để thoát khỏi ứng dụng thì việc đóng biểu mẫu hiện tại là không đủ. Chúng tôi phải sử dụng Application.Exit (0), v.v.
Peck_conyon

Nó đẹp, nhưng tôi nghĩ nó chỉ phù hợp với 2 hình thức. Điều gì về nhiều hình thức chuyển đổi giữa chúng ??
Tiến sĩ MAF

Điều này bị hạn chế đối với các biểu mẫu chạy theo trình tự, không song song hoặc chồng lên nhau, như OP đã yêu cầu. Tuy nhiên, tôi không chắc tại sao điều này sẽ bị hạn chế ở 2 dạng. Mã bên ngoài có thể tự do sinh ra nhiều dạng theo trình tự như mong muốn. Việc chuyển đổi giữa chúng cũng có thể được thực hiện bằng mã bên ngoài. Nó có thể kiểm tra một số trạng thái trên biểu mẫu chính (như loginForm.UserSuccessfullyAuthenticatedtrước đây) hoặc có thể trạng thái toàn cục để quyết định chạy lại biểu mẫu đăng nhập hay chạy biểu mẫu khác, hoặc có thể chấm dứt quá trình.
Manuzor

11

Các vấn đề xảy ra với dòng đó:

Application.Run(new Form1()); Có thể tìm thấy cái này trong tệp program.cs của bạn.

Dòng này chỉ ra rằng form1 là xử lý vòng lặp thông báo - nói cách khác, form1 chịu trách nhiệm tiếp tục thực thi ứng dụng của bạn - ứng dụng sẽ bị đóng khi form1 bị đóng.

Có một số cách để xử lý điều này, nhưng tất cả chúng theo cách này hay cách khác sẽ không đóng được form1.
(Trừ khi chúng tôi thay đổi loại dự án thành một thứ khác với ứng dụng biểu mẫu windows)

Tôi nghĩ là dễ nhất cho tình huống của bạn là tạo 3 biểu mẫu:

  • form1 - sẽ vẫn ẩn và hoạt động như một trình quản lý, bạn có thể gán nó để xử lý biểu tượng khay nếu bạn muốn.

  • form2 - sẽ có nút, khi được nhấp vào sẽ đóng form2 và sẽ mở form3

  • form3 - sẽ có vai trò của biểu mẫu khác cần được mở.

Và đây là mã mẫu để thực hiện điều đó:
(Tôi cũng đã thêm một ví dụ để đóng ứng dụng từ biểu mẫu thứ 3)

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


Lưu ý: làm việc với các bảng điều khiển hoặc tải các điều khiển động của người dùng mang tính học thuật hơn và thích hợp hơn như các tiêu chuẩn sản xuất trong ngành - nhưng với tôi, có vẻ như bạn chỉ đang cố gắng suy luận về cách mọi thứ hoạt động - vì mục đích đó, ví dụ này tốt hơn.

Và bây giờ các nguyên tắc đã được hiểu, chúng ta hãy thử nó chỉ với hai dạng:

  • Biểu mẫu đầu tiên sẽ giữ vai trò của người quản lý giống như trong ví dụ trước nhưng cũng sẽ hiển thị màn hình đầu tiên - vì vậy nó sẽ không bị đóng chỉ bị ẩn.

  • Hình thức thứ hai sẽ đóng vai trò hiển thị màn hình tiếp theo và bằng cách nhấp vào một nút sẽ đóng ứng dụng.


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

Nếu bạn thay đổi ví dụ trước - xóa form3 khỏi dự án.

Chúc may mắn.


6

Bạn không nói cụ thể, nhưng có vẻ như bạn đang cố gắng làm những gì tôi làm trong ứng dụng Win Forms của mình: bắt đầu với biểu mẫu Đăng nhập, sau đó sau khi đăng nhập thành công, hãy đóng biểu mẫu đó và tập trung vào biểu mẫu Chính. Đây là cách tôi làm điều đó:

  1. làm cho frmMain ở dạng khởi động; đây là những gì Program.cs của tôi trông như thế này:

    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new frmMain());
    }
    
  2. trong frmLogin của tôi, hãy tạo một thuộc tính công khai được khởi tạo thành false và chỉ đặt thành true nếu đăng nhập thành công xảy ra:

    public bool IsLoggedIn { get; set; }
    
  3. frmMain của tôi trông như thế này:

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

Không đăng nhập thành công? Thoát khỏi ứng dụng. Nếu không, hãy tiếp tục với frmMain. Vì đó là biểu mẫu khởi động, khi nó đóng, ứng dụng sẽ kết thúc.


3

sử dụng đoạn mã này trong biểu mẫu1 của bạn.

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

Tôi lấy cái này từ đây


Lưu ý rằng không khuyến khích các câu trả lời chỉ liên kết, các câu trả lời SO phải là điểm cuối của quá trình tìm kiếm giải pháp (so với một điểm dừng khác của các tài liệu tham khảo, có xu hướng cũ dần theo thời gian). Vui lòng xem xét thêm một bản tóm tắt độc lập ở đây, giữ liên kết làm tài liệu tham khảo.
kleopatra

2

Nếu bạn có hai biểu mẫu: frm_form1 và frm_form2. Mã sau được sử dụng để mở frm_form2 và đóng frm_form1. (Đối với ứng dụng biểu mẫu 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();

1

Tôi thường làm điều này để chuyển đổi qua lại giữa các biểu mẫu.

Đầu tiên, trong tệp Chương trình, tôi giữ ApplicationContext và thêm một phương thức SwitchMainForm của trình trợ giúp .

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


}

Sau đó, bất kỳ nơi nào trong mã bây giờ tôi gọi phương thức SwitchMainForm để dễ dàng chuyển sang biểu mẫu mới.

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

Nó sẽ không hoạt động. Không có ý nghĩa gì để ẩn trước khi hiển thị hình thức tiếp theo. Nó sẽ được thực thi cùng thời gian và chương trình sẽ bị kết thúc.
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
Điều gì về câu trả lời này thêm vào cuộc thảo luận này? Nó đang lặp lại mà không thêm bất kỳ thông tin giải thích nào có trong 9 câu trả lời khác.
Edward

0

Tôi nghĩ điều này dễ dàng hơn nhiều :)

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

    }

Giải pháp này không phải là một câu trả lời liên quan cho câu hỏi này. Giải pháp của bạn sẽ không đóng biểu mẫu hiện tại, điều này có nghĩa là biểu mẫu hiện tại vẫn đang được xử lý.
Ahmet Karabulut,

-1

Giả sử bạn có hai Form, Tên biểu mẫu đầu tiên là Form1 và tên biểu mẫu thứ hai là Form2. Bạn phải chuyển từ Form1 sang Form2 nhập mã vào đây. Viết mã như sau:

Trên Form1, tôi có một nút tên là Button1 và trên tùy chọn nhấp chuột của nó, hãy viết mã dưới đây:

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

Hy vọng mã này sẽ giúp bạn


Bốn phương pháp này: this.Visible=false; this.Hide(); this.Close(); this.Dispose();là thừa. Bạn không cần gì hơn Close(). Việc đóng một biểu mẫu sẽ loại bỏ nó, thiết lập khả năng hiển thị của biểu mẫu cũng giống như ẩn nó và ẩn một biểu mẫu là vô nghĩa khi nó sẽ không tồn tại trước sự kiện sơn tiếp theo.
Servy

-3

Tôi sẽ giải quyết nó bằng cách:

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 = falsevà sau đó this.Hide? Tại sao làm cùng một điều hai lần?
Neolisk

8
Ngoài ra, tại sao bạn lại tạo một cái mới Form1và không làm gì với nó?
Servy
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.