如何检查Windows窗体是否已打开,如果已关闭,则将其关闭?


79

我有一个表格“ fm”,它是一个简单的信息窗口,每10分钟会打开一次(fm.Show();)。

我如何每隔10分钟检查一次“ fm”表单是否打开,如果打开,则将其关闭并再次打开!

现在,总是使用fm创建表单,form fm = new form();
所以当我尝试检查表单是否打开时,即使以前有一个表单,它也总是false并打开一个新窗口!

我需要有一个为其赋予唯一标识的工具,然后检查是否打开了具有唯一标识的表单!

我不想只更新表单(fm)上的数据,因为我有一个带有按钮的复杂信息。

表单名称是 "UpdateWindow"

谢谢


1
为什么要再次打开它?您要创建新实例吗?我的意思是为什么您不想再调用一次Show方法?
默认语言环境

嗨,整个程序是我们公司的内部工具,它检查我们的某个程序是否有更新,它工作正常,但是我需要将其关闭并再次打开,因为它会获得更新的信息
数据库

2
您为什么不只是在表单中添加一个Timer组件并使用该计时器强制更新显示中的数据?更好的是,您可以将控件数据绑定到对象以自动更新状态。
克里斯·汤普森

2
我用这个解决方案解决它。Form fc = Application.OpenForms [“ UpdateWindow”]; 如果(fc!= null)fc.Close(); fm.Show(); 那你们觉得呢?
数据库2010年

声明该窗体类型的全局静态对象,将新创建的对象分配给该静态对象。处理时,将其设置为null。每次创建新表单时,请首先检查静态对象是否为null。这是比其他任何解决方案都更紧凑的解决方案。
拉里

Answers:


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)中使用它?
数据库

如果(frm是MyForm){/ * * /},应该可以解决问题。但是,如果仅用于更新,为什么不调用方法来更新数据?
萨沙(Sascha)2010年

12
我用这个...解决它。Form fc = Application.OpenForms [“ UpdateWindow”]; 如果(fc!= null)fc.Close(); fm.Show();
数据库2010年

1
我关闭表单后收到此错误:System.InvalidOperationException:'集合已修改;枚举操作可能无法执行。”
noobsee '17

45

我知道我来晚了...但是对于那些好奇的人...这是另一种方式

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

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

框架使用比公认的答案更好。
加斯帕79年

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

用于检查Form1是否已打开的CheckOpened定义:

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

实际上,我仍然不明白为什么您不更新表单上的数据。


这很有趣,但是我如何识别表格,我的意思是我们使用表格fm = new form(); 因此它始终是新表格,那么我如何识别该表格?
数据库

如果只有这样一种形式,则可以为其创建类级别的变量。如果一堆方法中创建了大量表单,则最好使用Sascha的方法)
默认语言环境

1
我通过检查表单是否按名称打开来解决它,如果打开则关闭它。Form fc = Application.OpenForms [“ UpdateWindow”]; 如果(fc!= null)fc.Close(); fm.Show();
数据库2010年


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

它将关闭form1,如果需要,您可以再次打开该表单:

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

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

Form1表格的名称在哪里。



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

请记住添加有关您在代码上正在执行的操作的更多信息
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();
    }
}

感谢您提供此代码段,它可能会提供一些有限的短期帮助。通过说明为什么这是一个很好的解决方案,正确的解释将大大提高其长期价值,对于其他存在类似问题的读者来说,这样做将更为有用。请编辑您的答案以添加一些解释,包括所做的假设
Shawn

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.