Windows Form이 이미 열려 있는지 확인하고 열려있는 경우 닫는 방법은 무엇입니까?


79

10 분마다 열리는 간단한 정보 창인 "fm" 양식이 있습니다 ( fm.Show();).

10 분마다 "fm" 양식 이 열려 있는지 확인 하고 열려 있으면 닫았다가 다시 열도록 할 수 있습니다!

이제 양식 fm은 항상 생성 form fm = new form();
되므로 양식이 열려 있는지 확인하려고 할 때 이전에 양식이 하나 있어도 항상 거짓이고 새 창을 엽니 다!

고유 한 신원을 부여 할 수있는 도구가 필요하며 고유 한 신원을 가진이 양식이 열렸는지 확인해야합니다!

버튼이있는 복잡한 정보가 있기 때문에 양식 (fm)의 데이터 만 업데이트하고 싶지 않습니다.

양식 이름은 "UpdateWindow"

감사


1
왜 다시 열고 싶습니까? 새 인스턴스를 생성 하시겠습니까? Show 메서드를 한 번 더 호출하고 싶지 않은 이유는 무엇입니까?
기본 로케일

안녕, 전체 프로그램은 우리 프로그램 중 하나에 대한 업데이트가 있는지 확인하는 우리 회사의 내부 도구입니다. 잘 작동했지만 업데이트 된 정보를 받기 때문에 닫았다가 다시 열어야합니다.
데이터베이스

2
양식에 타이머 구성 요소를 추가하고 타이머를 사용하여 디스플레이의 데이터를 강제로 업데이트하지 않는 이유는 무엇입니까? 더 좋은 점은 상태 자동 업데이트를 위해 컨트롤을 개체에 데이터 바인딩 할 수 있다는 것입니다.
Chris Thompson

2
이 솔루션으로 문제를 해결합니다. Form fc = Application.OpenForms [ "UpdateWindow"]; if (fc! = null) fc.Close (); fm.Show (); 그래서 여러분은 어떻게 생각하십니까?
데이터베이스

해당 양식 유형의 전역 정적 개체를 선언하고 새로 만든 개체를 해당 정적 개체에 할당합니다. 폐기시 null로 설정합니다. 새 양식을 만들 때마다 먼저 정적 개체가 null인지 아닌지 확인하십시오. 이것은 다른 어떤 것보다 더 컴팩트 한 솔루션입니다.
Lali

답변:


92

아마도 이것이 도움이 될 것입니다.

FormCollection fc = Application.OpenForms;

foreach (Form frm in fc)
{
//iterate through
     if (frm.Name == "YourFormName")
     {
         bFormNameOpen = true;
     }
}

foreach의 일부 코드는 특정 형식을 감지하고 수행 할 수 있습니다. 그래도 테스트되지 않았습니다.

에서 찾을 수 http://bytes.com/topic/c-sharp/answers/591308-iterating-all-open-forms


감사합니다. 내 양식 (fm)과 함께 사용하는 방법은 무엇입니까?
Data-Base

if (frm is MyForm) {/ * * /}, 트릭을 수행해야합니다. 그러나 단지 업데이트를위한 것이라면 데이터를 업데이트하는 메서드를 호출하지 않는 이유는 무엇입니까?
Sascha

12
이 문제를 해결합니다 .... Form fc = Application.OpenForms [ "UpdateWindow"]; if (fc! = null) fc.Close (); fm.Show ();
데이터베이스

1
양식을 닫은 후이 오류가 발생했습니다. System.InvalidOperationException : 'Collection was modified; 열거 작업이 실행되지 않을 수 있습니다. '
noobsee

45

늦었다는 건 알지만 ... 궁금한 분들을 위해 ...

if (Application.OpenForms.OfType<UpdateWindow>().Count() == 1)
    Application.OpenForms.OfType<UpdateWindow>().First().Close();

UpdateWindow frm = new UpdateWindow()
frm.Show();

허용 된 답변 imho보다 훨씬 더 나은 프레임 워크 사용.
Gaspa79

14

메뉴에서 양식을 호출하고 MDI 양식을 클릭한다고 가정하면 다음과 같이 최상위 수준에서 해당 양식의 인스턴스 선언을 만들어야합니다.

Form1 fm = null;

그런 다음 다음과 같이 Form1을 호출하는 메뉴 클릭 이벤트를 정의해야합니다.

private void form1ToolStripMenuItem_Click(object sender, EventArgs e)
{
    if (fm == null|| fm.Text=="")
    {
        fm = new Form1();              
        fm.MdiParent = this;
        fm.Dock = DockStyle.Fill;
        fm.Show();
    }
    else if (CheckOpened(fm.Text))
    {
        fm.WindowState = FormWindowState.Normal;
        fm.Dock = DockStyle.Fill;
        fm.Show();
        fm.Focus();               
    }                   
}

CheckOpened는 Form1에 이미 열거 나하지되어 있는지 확인하기 위해 정의 :

private bool CheckOpened(string name)
{
    FormCollection fc = Application.OpenForms;

    foreach (Form frm in fc)
    {
        if (frm.Text == name)
        {
            return true; 
        }
    }
    return false;
}

이것이 이미 열려 있거나 최소화 된 경우 메뉴 클릭시 Form1에 초점을 맞추는 양식의 여러 인스턴스를 만드는 문제가 해결되기를 바랍니다.


10

나는 그 진술을 이해했는지 잘 모르겠습니다. 도움이 되었기를 바랍니다. 이 폼의 인스턴스를 하나만 사용하려면 사용자 닫기시 Form.Dispose 호출을 방지해야합니다 . 이를 위해 자식 폼의 Closing 이벤트를 처리 할 수 ​​있습니다.

private void ChildForm_FormClosing(object sender, FormClosingEventArgs e)
{
    this.Hide();
    e.Cancel = true;
}

그런 다음 새 인스턴스를 만들 필요가 없습니다 frm. 인스턴스에서 Show 메서드를 호출하기 만하면됩니다.

Form.Visible 속성을 확인하여 현재 양식이 열려 있는지 확인할 수 있습니다.

private ChildForm form = new ChildForm();

private void ReopenChildForm()
{
    if(form.Visible)
    {
        form.Hide();
    }
    //Update form information
    form.Show();
}

사실, 양식의 데이터를 업데이트하지 않는 이유를 여전히 이해하지 못합니다.


이것은 흥미 롭습니다. 그러나 제가 어떻게 양식을 식별 할 수 있는지, 저는 우리가 form fm = new form (); 그래서 그것은 항상 새로운 양식입니다. 그래서 양식을 어떻게 식별 할 수 있습니까?
Data-Base

그러한 양식이 하나뿐이면 클래스 수준 변수를 만들 수 있습니다. 여러 메서드에서 생성 된 많은 양식이있는 경우 Sascha의 접근 방식을 사용하는 것이 좋습니다)
기본 로케일

1
폼이 이름으로 열려 있는지 확인하여 해결하고 열려 있으면 닫습니다. Form fc = Application.OpenForms [ "UpdateWindow"]; if (fc! = null) fc.Close (); fm.Show ();
Data-Base


2
Form1 fc = Application.OpenForms["Form1 "] != null ? (Form1 ) Application.OpenForms["Form1 "] : null;
if (fc != null)
{
    fc.Close();
}

다음을 사용하여 원하는 경우 해당 양식을 다시 열 수 있습니다.

Form1 frm = New Form1();
frm.show();

1
if( ((Form1)Application.OpenForms["Form1"]).Visible == true)
    //form is visible
else
    //form is invisible

Form1양식의 이름은 어디에 있습니까 ?


1

이것을 시도하면 작동합니다.

//inside main class
Form1 Fm1 = new Form1();<br>

//in button click
if (Fm1.IsDisposed)
{
    Fm1 = new Form();
}
Fm1.Show();
Fm1.BringToFront();
Fm1.Activate();

1
if (Application.OpenForms["Form_NAME"] == null)
{
   new Form_NAME().Show();
}

양식 인스턴스가 열려 있지 않으면 IF 루프에 들어갑니다.


1

MDICHILD 기능을 사용해보십시오

public void mdiChild(Form mdiParent, Form mdiChild)
{
    foreach (Form frm in mdiParent.MdiChildren)
    {
        // check if name equals
        if (frm.Name == mdiChild.Name)
        {
            //close if found

            frm.Close();

            return;
        }
    }

    mdiChild.MdiParent = mdiParent;

    mdiChild.Show();

    mdiChild.BringToFront();
}

0

아래에 연결해보세요.

private void frmMyForm_Deactivate(object sender, EventArgs e)
    {
        // Raise your flag here.
    }

이벤트 위의 연결을 통해 양식이 최소화 될 때마다 다른 양식에 의해 부분적으로 / 완전히 숨겨 질 때마다 알려줍니다.


0

이것은 내가 모든 열린 양식을 닫는 데 사용한 것입니다 (기본 양식 제외)

    private void CloseOpenForms()
    {

           // Close all open forms - except for the main form.  (This is usually OpenForms[0].
           // Closing a form decrmements the OpenForms count
           while (Application.OpenForms.Count > 1)
           {
               Application.OpenForms[Application.OpenForms.Count-1].Close();
           }
    }

0

재미 있네요.이 스레드에 추가해야했습니다.

1) form.show ()에 전역 변수를 추가하고 form.close ()에서 변수를 지 웁니다.

2) 부모 양식에 타이머를 추가하십시오. 자녀 양식을 열어두고 10 분마다 데이터를 업데이트하십시오.

3) 자식 폼에 타이머를 넣어 데이터를 업데이트합니다.


0

* 희망이 당신을 위해 작동합니다

System.Windows.Forms.Form f1 = System.Windows.Forms.Application.OpenForms["Order"];
if(((Order)f1)!=null)
{
//open Form
}
else
{
//not open
}

0

이 시도

 bool IsOpen = false;
    foreach (Form f in Application.OpenForms)
    {
        if (f.Text == "Form2")
        {
            IsOpen = true;
            f.Focus();
            break;
        }
    }

    if (IsOpen == false)
    {
        Form2 f2 = new Form2();
        f2.MdiParent = this;
        f2.Show();
    }

0
 private static Form IsFormAlreadyOpen(Type formType)
 {
     return Application.OpenForms.Cast<Form>().FirstOrDefault(openForm => openForm.GetType() == formType);
 }

이 코드 스 니펫은 질문을 해결할 수 있지만 설명을 포함하면 게시물의 품질을 향상시키는 데 큰 도움이됩니다. 미래에 독자를 위해 질문에 답하고 있으며 해당 사용자는 코드 제안 이유를 모를 수 있습니다. 또한 코드와 설명의 가독성을 감소 시키므로 설명 주석으로 코드를 혼잡하게 만들지 마십시오!
안녕 StackExchange

0

한 번만 형성

양식의 여러 삽입을 허용하는 것이 목표 인 경우 다음을 고려하십시오.

public class MyForm : Form
{
    private static MyForm alreadyOpened = null;

    public MyForm()
    {
        // If the form already exists, and has not been closed
        if (alreadyOpened != null && !alreadyOpened.IsDisposed)
        {
            alreadyOpened.Focus();            // Bring the old one to top
            Shown += (s, e) => this.Close();  // and destroy the new one.
            return;
        }           

        // Otherwise store this one as reference
        alreadyOpened = this;  

        // Initialization
        InitializeComponent();
    }
}

0
Form user_rpt = Application.OpenForms["frmUesr_reports"];
        if (user_rpt == null)
        {
            /// Do Something here
        }

이것을 시도 이것은 양식이 열려 있는지 여부를 확인하는 간단한 아이디어입니다.


0

내 앱에는 여러 다른 양식 (하위 양식)으로 이동할 수있는 버튼이있는 메인 메뉴 양식이 있습니다. 한 번에 각 하위 양식의 인스턴스 하나만 실행하고 싶었습니다. 또한 사용자가 이미 존재하는 하위 양식을 실행하려고 시도하면 하위 양식이 최소화되거나 다른 앱 창 뒤에 "front & center"가 표시되도록하고 싶었습니다. 현재 가장 많이 찬성 된 답변을 사용하여 답변을 다음과 같이 리팩토링했습니다.

private void btnOpenSubForm_Click(object sender, EventArgs e)
    {

        Form fsf = Application.OpenForms["formSubForm"];

        if (fsf != null)
        {
            fsf.WindowState = FormWindowState.Normal;
            fsf.Show();
            fsf.TopMost = true;
        }
        else
        {
            Form formSubForm = new FormSubForm();
            formSubForm.Show();
            formSubForm.TopMost = true;
        }
    }

0

이것은 나를 형성했습니다.

public void DetectOpenedForm()
{
    FormCollection AllForms = Application.OpenForms;
    Boolean FormOpen = false;
    Form OpenedForm = new Form();
    foreach (Form form in AllForms)
    {
        if (form.Name == "YourFormName")
        {
            OpenedForm = form;
            FormOpen = true;
        }
    }
    if (FormOpen == true)
    {
        OpenedForm.Close();
    }
}

Remenber 당신은 당신의 코드에 무슨 일을하는지에 대한 자세한 정보를 추가 할
xsami

0

내 방법이 가장 간단 하다고 생각합니다 .

    Form2 form2 = null;
    private void SwitchFormShowClose_Click(object sender, EventArgs e)
    {  
        if(form2 == null){
            form2 = new Form2();
            form2.Show();
        }
        else{
            form2.Close();
            form2 = null;
        }
    }

0

아래는 실제로 매우 잘 작동합니다.

private void networkInformationToolStripMenuItem_Click(object sender, EventArgs e)
{
    var _open = false;
    FormCollection fc = Application.OpenForms;
    foreach (Form frm in fc)
    {
        if (frm.Name == "FormBrowseNetworkInformation")
        {
            _open = true;
            frm.Select();
            break;
        }
    }
    if (_open == false)
    {
        var formBrowseNetworkInformation = new FormBrowseNetworkInformation();
        formBrowseNetworkInformation.Show();
    }
}

제한된 단기적인 도움을 제공 할 수있는이 코드 스 니펫에 감사드립니다. 적절한 설명 이것이 문제에 대한 좋은 해결책 인 이유를 보여줌으로써 장기적인 가치를 크게 향상시키고 다른 유사한 질문을 가진 미래의 독자에게 더 유용하게 만들 것입니다. 당신이 만든 가정을 포함하여 몇 가지 설명을 추가 할 답변을 수정하십시오
숀 C.

0

이것은 확실히 말할 것입니다. 나도이 기능을 사용한다.

  public static bool isFormOpen(Form formm)
    {

        foreach (Form OpenForm in Application.OpenForms)
        {
            if (OpenForm.Name == formm.Name)
            {
                return true;
            }
        }

        return false;
    }

0

내가 작성한 이전 게시물을 수정했습니다. 이 작업은 모든 열린 양식을 반복 할 필요없이 완벽하게 작동합니다.

        Form fc = Application.OpenForms["FormBrowse"];
        if (fc != null)
        {
            fc.Select();
        }
        else
        {
            var formBrowse = new FormBrowse();
            formBrowse.Show();
        }

0

양식을 반복 할 필요가 없습니다.

if(Application.OpenForms["<your_form_name>"] != null){

   //Your form is already open

}
else {

  //Your form isn't open

}

0

이것은 두 번째 양식이 이미 열려 있는지 확인하고 buttong 클릭에서 다시 열지 않으려면 작동합니다.

 int formcheck = 0;
    private void button_click()
    {
       Form2Name myForm2 = new Form2Name();
       if(formcheck == 0)
       {
          myForm2.Show(); //Open Form2 only if its not active and formcheck == 0
          // Do Somethin

          formcheck = 1; //Set it to 1 indicating that Form2 have been opened
       {   
    {

-1

또한 이것이 도움이 될 수 있습니다.


class Helper
    {
        public void disableMultiWindow(Form MdiParent, string formName)
        {
            FormCollection fc = Application.OpenForms;
            try
            {
                foreach (Form form in Application.OpenForms)
                {
                    if (form.Name == formName)
                    {
                        form.BringToFront();
                        return;
                    }
                }

                Assembly thisAssembly = Assembly.GetExecutingAssembly();
                Type typeToCreate = thisAssembly.GetTypes().Where(t => t.Name == formName).First();
                Form myProgram = (Form)Activator.CreateInstance(typeToCreate);
                myProgram.MdiParent = MdiParent;
                myProgram.Show();
            }
            catch (Exception ex) { MessageBox.Show(ex.Message); }
        }
    }

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.