¿Cómo comprobar si un formulario de Windows ya está abierto y cerrarlo si lo está?


79

Tengo un formulario "fm" que es una ventana de información simple que se abre cada 10 minutos ( fm.Show();).

¡Cómo puedo hacer que cada 10 minutos verifique si el formulario "fm" está abierto y si está abierto lo cierra y lo abre de nuevo!

Ahora, el formulario fm siempre se crea con, form fm = new form();
por lo que cuando trato de verificar si el formulario está abierto, siempre será falso y abrirá una nueva ventana incluso si hay un formulario antes.

¡Necesito tener una herramienta para darle una identidad única y luego verificar si este formulario con identidad única está abierto o no!

No quiero simplemente actualizar los datos en el formulario (fm), porque tengo una información complicada con botones.

El nombre del formulario es "UpdateWindow"

Gracias


1
¿Por qué quieres abrirlo de nuevo? ¿Quieres crear una nueva instancia? Quiero decir, ¿por qué no quieres llamar al método Show una vez más?
configuración regional predeterminada

hola, todo el programa es una herramienta interna en nuestra empresa que verifica si hay una actualización para uno de nuestros programas, funcionó bien, pero lo necesito para cerrarlo y abrirlo nuevamente porque obtiene información actualizada
Base de datos

2
¿Por qué no agrega un componente Timer al formulario y usa el temporizador para forzar una actualización de los datos en la pantalla? Aún mejor, podría vincular los controles a un objeto para la actualización automática del estado.
Chris Thompson

2
Lo resuelvo con esta solución ... Form fc = Application.OpenForms ["UpdateWindow"]; if (fc! = null) fc.Close (); fm.Show (); entonces, ¿qué piensan chicos?
Base de datos

Declare un objeto estático global de ese tipo de formulario, asigne un objeto recién creado a ese objeto estático. Al desechar, establézcalo en nulo. cada vez que cree un formulario nuevo, compruebe primero si el objeto estático es nulo o no. Esta es una solución más compacta que cualquier otra.
Lali

Respuestas:


92

tal vez esto ayude:

FormCollection fc = Application.OpenForms;

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

Algún código en el foreach para detectar la forma específica y se podría hacer. Sin embargo, no probado.

Encontrado en http://bytes.com/topic/c-sharp/answers/591308-iterating-all-open-forms


Gracias, entonces, ¿cómo usarlo con mi formulario (fm)?
Base de datos

if (frm es MyForm) {/ * * /}, debería hacer el truco. Pero si es solo para actualizar, ¿por qué no llamar a un método para actualizar los datos?
Sascha

12
Lo soluciono con esto .... Form fc = Application.OpenForms ["UpdateWindow"]; if (fc! = null) fc.Close (); fm.Show ();
Base de datos

1
Recibí este error después de cerrar el formulario con él: System.InvalidOperationException: 'La colección fue modificada; la operación de enumeración puede no ejecutarse. '
noobsee

45

Sé que llego tarde ... Pero para los curiosos ... Esta es otra forma

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

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

Mucho mejor uso del marco que la respuesta aceptada en mi humilde opinión.
Gaspa79

14

Supongamos que si estamos llamando a un formulario desde un menú, haga clic en el formulario MDI, entonces necesitamos crear la declaración de instancia de ese formulario en el nivel superior como este:

Form1 fm = null;

Luego, necesitamos definir el evento de clic de menú para llamar al Form1 de la siguiente manera:

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

El CheckOpened definido para verificar que Form1 ya está abierto o no:

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

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

Espero que esto resuelva los problemas al crear múltiples instancias de un formulario y que también se enfoque en Form1 al hacer clic en el menú si ya está abierto o minimizado.


10

No estoy seguro de haber entendido la declaración. Espero que esto ayude. Si desea operar con una sola instancia de este formulario, debe evitar que Form.Dispose llame al cierre del usuario. Para hacer esto, puede manejar el evento de cierre del formulario secundario.

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

Y luego no es necesario crear nuevas instancias de frm. Simplemente llame al método Show en la instancia.

Puede consultar la propiedad Form.Visible para comprobar si el formulario está abierto en este momento.

private ChildForm form = new ChildForm();

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

De hecho, todavía no entiendo por qué no actualizas los datos del formulario.


esto es interesante, pero cómo puedo identificar la forma, quiero decir que usamos form fm = new form (); por lo que siempre es una forma nueva, entonces, ¿cómo puedo identificar la forma?
Base de datos

Si es solo uno de esos formularios, puede crear una variable de nivel de clase para él. Si hay muchos formularios creados en el grupo de métodos, es mejor que use el enfoque de Sascha)
configuración regional predeterminada

1
Lo soluciono comprobando si el formulario se abre por nombre y luego lo cierro si está abierto Formulario fc = Application.OpenForms ["UpdateWindow"]; if (fc! = null) fc.Close (); fm.Show ();
Base de datos

4
Form fc = Application.OpenForms["UpdateWindow"]; 

if (fc != null) 
   fc.Close(); 

fc.Show();

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

Se cerrará el formulario1, puede abrir ese formulario nuevamente si lo desea usando:

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

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

donde Form1está el nombre de tu formulario.


1

Prueba esto, funcionará:

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

Si la instancia del formulario no está abierta, ingresará al bucle IF.


1

prueba esta función 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

Intenta cablear abajo

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

Al cablear el evento anterior, le dirá cuando el formulario se minimiza, parcialmente o totalmente oculto por otro formulario.


0

Esto es lo que usé para cerrar todos los formularios abiertos (excepto el formulario principal)

    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

Es curioso, tuve que agregar algo a este hilo.

1) Agregue una var global en form.show () y borre la var en form.close ()

2) En el formulario principal, agregue un temporizador. Mantenga abierto el formulario secundario y actualice sus datos cada 10 minutos.

3) ponga un temporizador en el formulario secundario para actualizar los datos por sí mismo.


0

* Espero que esto funcione para ti

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

0

prueba esto

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

Si bien este fragmento de código puede resolver la pregunta, incluir una explicación realmente ayuda a mejorar la calidad de su publicación. Recuerde que está respondiendo la pregunta para los lectores en el futuro, y es posible que esas personas no conozcan los motivos de su sugerencia de código. Por favor, trate también de no llenar su código con comentarios explicativos, ya que esto reduce la legibilidad tanto del código como de las explicaciones.
Adiós StackExchange

0

Forma solo una vez

Si su objetivo es marcar pocas instancias de un formulario, considere seguir ...

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
        }

Pruebe esto Esta es la idea breve para verificar que el formulario esté abierto o no abierto


0

En mi aplicación, tenía un formulario de menú principal que tenía botones para navegar a una variedad de otros formularios (también conocidos como subformularios). Quería que solo se ejecutara una instancia de cada subformulario a la vez. Además, quería asegurarme de que si un usuario intentaba iniciar un subformulario ya existente, el subformulario se vería obligado a mostrarse "al frente y al centro" si se minimiza o detrás de otras ventanas de la aplicación. Usando las respuestas actualmente más votadas, refactoricé sus respuestas en esto:

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

Esto funcionó para mí:

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

Recuerde agregar más información sobre lo que está haciendo en su código
xsami

0

Creo que mi método es el más sencillo .

    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

Lo siguiente en realidad funciona muy bien.

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

Gracias por este fragmento de código, que puede proporcionar una ayuda limitada a corto plazo. Una explicación adecuada mejoraría enormemente su valor a largo plazo al mostrar por qué es una buena solución al problema y lo haría más útil para futuros lectores con otras preguntas similares. Edite su respuesta para agregar alguna explicación, incluidas las suposiciones que hizo
Shawn C.

0

esta palabra definitivamente. Yo también uso esta función para mí.

  public static bool isFormOpen(Form formm)
    {

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

        return false;
    }

0

Modifiqué una publicación anterior que hice. Esto funciona a la perfección sin tener que repetir todas las formas abiertas.

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

0

intente esto, no es necesario recorrer los formularios:

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

   //Your form is already open

}
else {

  //Your form isn't open

}

0

Esto funciona si desea verificar si el segundo formulario ya está abierto y evitar abrirlo nuevamente con un clic.

 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

Además, puede que esto ayude


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

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.