c # 새 양식을 연 다음 현재 양식을 닫으시겠습니까?


89

예를 들어, 내가 양식 1에 있다고 가정하면 다음을 원합니다.

  1. 양식 2 열기 (양식 1의 단추에서)
  2. 양식 1 닫기
  3. 양식 2에 집중

18
끔찍한 사용성. WinForms를 사용하는 경우 컨테이너 창을 만들고 대신 패널을 바꿉니다. 사용자는 그것을 위해 당신을 사랑합니다 (그리고 그 일을하지 당신을 싫어)합니다
클로스 Jørgensen은

1
클로스를 들어라! 달성하려는 것은 아마도 a) 마법사와 같은 일련의 단계의 winforms 구현 또는 b) "데이터 입력 / 제출"양식 다음에 "결과"양식을 표시하려는 시도입니다. a) 또는 b) 구현하려는 UI 동작은 차선책입니다.
Simen S 2011

Clause와 Simen S에게 대단히 감사합니다. 귀하의 의견은 저와 같은 초보자에게 매우 유용합니다. GUI와 사용성에 대한 더 많은 튜토리얼을 읽을 것입니다. 유용한 것들을 추천 해 주시겠습니까?
tnhan07 2011


실제 의도가 로그인 (또는 유사) 양식을 갖는 것이 었으면 [답변] ( stackoverflow.com/questions/4759334/… ) 도 확인하십시오 .
ilias iliadis

답변:


193

Steve의 솔루션이 작동하지 않습니다. this.Close ()를 호출하면 현재 폼이 form2와 함께 삭제됩니다. 따라서 이것을 숨기고 form2.Closed 이벤트를 설정하여 this.Close ()를 호출해야합니다.

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

2
닷넷의 윈도우 폼에는 Closed 이벤트가 없습니다. 당신이 나에게 말할 수있는 것은 이벤트 FormClosed입니다
안 잘리

2
첫 번째 양식을 숨기는 것이 여전히 기억을 유지하지 않습니까? 그 자원을 어떻게 해제 할 수 있습니까?
user2635088 2015

5
form2.Closed += (s, args) => this.Close();이 진술이 어떻게 작동하는지 알 수 있습니까? 정확히 무엇 (s,args)입니까?
야쉬 Saraiya

1
(s, args) => this.Close();람다 식입니다. form2.Closed이벤트가 시작될 때 호출되는 "제자리"함수를 만듭니다 . (s, args)람다에 대한 매개 변수의 이름 일뿐입니다. 이벤트 핸들러의 경우 일반적으로 (object sender, EventArgs e). Closed이벤트 대리자 서명이 해당 유형을 설명 하기 때문에 유형이 제공되지 않습니다 (필요한 경우 누군가 내 문구를 수정하십시오). // 전체적으로 이벤트를 처리하는 현재 함수 외부에서 전체 함수 (이벤트 핸들러)를 선언 할 필요가없는 까다로운 방법 Form2.Closed입니다.
KDecker

1
그 단지 첫 번째 양식을 숨기고 새 양식을 열고 있지만 첫 번째 폼을 닫는
Uddyan Semwal

25

이렇게 해보세요 ...

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

여기에 문제가 있습니다. 기본 양식이 있습니다. 그러나 나는 로그인을 위해 작은 양식을 사용합니다. 이 양식은이 메서드를 사용하여 Main Form을 호출합니다. 좋습니다. 문제는 Main Form에 자식 Form이 표시되고 자식 Form을 닫을 때 Main Form도 닫힙니다. 그래서 저는 Nihique에서 발표 한 방법을 사용하고 있기 때문에. 코드는 좋은 있도록 노력하고 있습니다 ...!
MontDeska

이 코드는 나를 위해 일하고 있습니다. 내가 VS 2015 년 감사를 사용하고
IT 동영상 블로그

21

다른 답변은 이미 많은 다른 방법을 설명했습니다. 그러나 그들 중 많은 사람들이 관련 ShowDialog()되거나 form1열려 있지만 숨겨져 있습니다. 내 생각에 가장 직관적이고 가장 직관적 인 방법은 단순히 닫은 form1다음 form2외부 위치에서 생성 하는 것입니다. 경우 form1에 생성 된 Main, form2간단하게 사용하여 만들 수 있습니다 Application.Run처럼 form1전에. 다음은 예제 시나리오입니다.

어떻게 든 인증하려면 사용자가 자격 증명을 입력해야합니다. 이후 인증이 성공하면 메인 애플리케이션을 사용자에게 보여주고 싶습니다. 이를 수행하기 위해 두 가지 형식을 사용합니다 : LogingFormMainForm. 에 LoginForm인증이 성공했는지 여부를 결정하는 플래그가 있습니다. 이 플래그는 MainForm인스턴스 를 만들지 여부를 결정하는 데 사용됩니다 . 이 두 양식 모두 다른 양식에 대해 알 필요가 없으며 두 양식 모두 정상적으로 열고 닫을 수 있습니다. 이에 대한 코드는 다음과 같습니다.

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

이것은 양식을 숨기는 것보다 좋은 트릭입니다. 응용 프로그램을 종료 할 숨겨진 양식이있는 경우 현재 양식을 닫는 것만으로는 충분하지 않습니다. Application.Exit (0) 등을 사용해야합니다.
Peck_conyon

좋지만 2 가지 형태에만 적합하다고 생각합니다. 그들 사이를 전환하는 여러 양식은 어떻습니까 ??
MAF 박사

이것은 OP가 요청했듯이 병렬로 또는 서로 위에 양식을 실행하지 않고 순서대로 실행하는 것으로 제한됩니다. 그래도 왜 이것이 2 가지 형태로 제한되는지 잘 모르겠습니다. 외부 코드는 원하는만큼 순서대로 많은 양식을 생성 할 수 있습니다. 그들 사이의 토글은 외부 코드로도 할 수 있습니다. 메인 폼의 일부 상태 ( loginForm.UserSuccessfullyAuthenticated이전 과 같은 ) 또는 전역 상태를 확인하여 로그인 폼을 다시 실행할지, 다른 폼을 실행할지 또는 프로세스를 종료할지 결정할 수 있습니다.
Manuzor

11

그 라인의 문제 존재 :

Application.Run(new Form1()); program.cs 파일에서 찾을 수 있습니다.

이 줄은 form1이 메시지 루프를 처리한다는 것을 나타냅니다. 즉, form1이 응용 프로그램을 계속 실행해야합니다. form1이 닫히면 응용 프로그램이 닫힙니다.

이를 처리하는 방법에는 여러 가지가 있지만 모두 어떤 식 으로든 form1을 닫지 않습니다.
(프로젝트 유형을 Windows Forms 응용 프로그램 이외의 것으로 변경하지 않는 한)

내가 생각하기에 가장 쉬운 방법은 3 가지 양식을 만드는 것입니다.

  • form1-표시되지 않고 관리자 역할을하며 원하는 경우 트레이 아이콘을 처리하도록 지정할 수 있습니다.

  • form2-버튼을 클릭하면 form2가 닫히고 form3이 열립니다.

  • form3-열어야하는 다른 양식의 역할을 갖습니다.

다음은이를 수행하는 샘플 코드입니다.
(또한 세 번째 양식에서 앱을 닫는 예제를 추가했습니다.)

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


참고 : 패널로 작업하거나 사용자 컨트롤을 동적으로로드하는 것이 산업 프로덕션 표준으로 더 학문적이고 선호됩니다.

이제 원칙이 이해되었으므로 두 가지 형식으로 시도해 보겠습니다.

  • 첫 번째 양식은 이전 예에서와 같이 관리자 역할을 맡지 만 첫 번째 화면도 표시하므로 닫히지 않고 숨겨집니다.

  • 두 번째 양식은 다음 화면을 표시하는 역할을하며 버튼을 클릭하면 애플리케이션이 닫힙니다.


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

이전 예제를 변경하는 경우-프로젝트에서 form3을 삭제하십시오.

행운을 빕니다.


6

구체적이지는 않았지만 Win Forms 앱에서 내가하는 일을하려는 것 같습니다. 로그인 양식으로 시작한 다음 성공적인 로그인 후 해당 양식을 닫고 기본 양식에 초점을 둡니다. 방법은 다음과 같습니다.

  1. frmMain을 시작 양식으로 만듭니다. 이것은 내 Program.cs의 모습입니다.

    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new frmMain());
    }
    
  2. 내 frmLogin에서 성공적인 로그인이 발생한 경우에만 false로 초기화되고 true로 설정되는 공용 속성을 만듭니다.

    public bool IsLoggedIn { get; set; }
    
  3. 내 frmMain은 다음과 같습니다.

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

로그인에 성공하지 못했습니까? 응용 프로그램을 종료하십시오. 그렇지 않으면 frmMain으로 계속하십시오. 시작 양식이므로 닫히면 응용 프로그램이 종료됩니다.


3

이 코드 조각을 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();
}

나는 여기 에서 이것을 얻었다


링크 전용 답변은 권장되지 않으며 SO 답변은 솔루션 검색의 끝 점이되어야합니다 (시간이 지남에 따라 부실 해지는 경향이있는 참조의 또 다른 중간 지점과 비교). 여기에 독립형 시놉시스를 추가하고 링크를 참조로 유지하십시오.
kleopatra

2

두 가지 양식이있는 경우 : frm_form1 및 frm_form2. 다음 코드는 frm_form2를 열고 frm_form1을 닫는 데 사용됩니다. (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

나는 일반적으로 양식을 앞뒤로 전환하기 위해이 작업을 수행합니다.

첫째, 프로그램 파일 에서 ApplicationContext를 유지 하고 도우미 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();
    }


}

그런 다음 코드의 어느 곳에서나 SwitchMainForm 메서드를 호출 하여 새 양식으로 쉽게 전환합니다.

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

작동하지 않습니다. 다음 양식을 표시하기 전에 숨길 의미가 없습니다. 동시에 실행되고 프로그램이 종료됩니다.
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
이 답변에 대해이 토론에 추가되는 것은 무엇입니까? 9 개의 다른 답변에 설명 정보를 추가하지 않고 다시 시작합니다.
Edward

0

나는 이것이 훨씬 쉽다고 생각한다. :)

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

    }

이 솔루션은이 질문에 대한 관련 답변이 아닙니다. 솔루션은 현재 양식을 닫지 않습니다. 이는 현재 양식이 아직 처리 중임을 의미합니다.
Ahmet Karabulut

-1

두 개의 Form, First Form Name이 Form1이고 두 번째 form 이름이 Form2라고 가정하면 Form1에서 Form2로 점프하여 여기에 코드를 입력해야합니다. 다음과 같은 코드를 작성하십시오.

Form1에는 Button1이라는 버튼이 하나 있고 클릭 옵션에서 아래 코드를 작성합니다.

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

이 코드가 도움이되기를 바랍니다.


이 네 가지 방법 this.Visible=false; this.Hide(); this.Close(); this.Dispose();은 중복됩니다. 이상은 필요하지 않습니다 Close(). 양식을 닫으면 양식이 처리되고 양식의 가시성을 설정하는 것은 양식을 숨기는 것과 동일하며 양식을 숨기는 것은 다음 페인트 이벤트 전에 존재하지 않을 때 의미가 없습니다.
Servy

-3

다음을 수행하여 해결할 것입니다.

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 = false그리고 this.Hide? 똑같은 일을 두 번하는 이유는 무엇입니까?
Neolisk 2011

8
또한 왜 새로운 것을 만들고 Form1그것으로 아무것도하지 않는가?
Servy
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.