Pregunta

¿Cómo evitar múltiples instancias de ventanas en C #? Quiero solo una instancia del formulario en ejecución. Porque hay posibilidades de abrir el mismo formulario desde muchas páginas de mi aplicación.

¿Fue útil?

Solución

implementar el patrón de Singleton

un ejemplo: CodeProject: Simple Singleton Forms (ok, está en VB .NET, pero solo para darte una pista)

Otros consejos

Sí, tiene patrón de singleton,

Código para crear un objeto singleton,

public partial class Form2 : Form
{
 .....
 private static Form2 inst;
 public static Form2  GetForm
 {
   get
    {
     if (inst == null || inst.IsDisposed)
         inst = new Form2();
     return inst;
     }
 }
 ....
}

Invocar / Mostrar este formulario,

Form2.GetForm.Show();

Cuando visualice el diálogo, simplemente use .ShowDialog (); en lugar de .Show();

Una de las soluciones que apliqué a mi proyecto para volver a poner este formulario en primer plano es:

    private bool checkWindowOpen(string windowName)
    {
        for (int i = 0; i < Application.OpenForms.Count; i++)
        {
            if (Application.OpenForms[i].Name.Equals(windowName))
            {
                Application.OpenForms[i].BringToFront();
                return false;
            }
        }
        return true;
    }

windowName es esencialmente el nombre de clase de su formulario de Windows y el valor de retorno se puede usar para no crear una nueva instancia de formulario.

Si su sistema tiene la posibilidad de mostrar el mismo tipo de formulario para diferentes datos de instancia, podría crear un sistema de verificación que itere todos los formularios abiertos existentes, buscando un identificador de datos de instancia único y luego volver a mostrar cualquier formulario encontrado.

por ejemplo tener una clase de formulario 'CustomerDetails' que contiene una propiedad pública 'CustomerUniqueID':

foreach(Form f in CurrentlyDisplayedForms)
{
    CustomerDetails details = f as CustomerDetails;
    if((details != null) && (details.CustomerUniqueUD == myCustomerID))
    {
        details.BringToFront();
    }
    else
    {
        CustomerDetails newDetail = new CustomerDetails(myCustomerID);
    }
}

También utilizamos el mismo mecanismo para forzar automáticamente las actualizaciones del enlace de datos donde los datos de un cliente se han editado y guardado.

Aquí está mi solución en ShowForm ():

    private void ShowForm(Type typeofForm, string sCaption)
    {
        Form fOpen = GetOpenForm(typeofForm);
        Form fNew = fOpen;
        if (fNew == null)
            fNew = (Form)CreateNewInstanceOfType(typeofForm);
        else
            if (fNew.IsDisposed)
                fNew = (Form)CreateNewInstanceOfType(typeofForm);

        if (fOpen == null)
        {
            fNew.Text = sCaption;
            fNew.ControlBox = true;
            fNew.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
            fNew.MaximizeBox = false;
            fNew.MinimizeBox = false;
            // for MdiParent
            //if (f1.MdiParent == null)
            //    f1.MdiParent = CProject.mFMain;
            fNew.StartPosition = FormStartPosition.Manual;
            fNew.Left = 0;
            fNew.Top = 0;
            ShowMsg("Ready");
        }
        fNew.Show();
        fNew.Focus();
    }
    private void aboutToolStripMenuItem_Click(object sender, EventArgs e)
    {
        ShowForm(typeof(FAboutBox), "About");
    }

    private Form GetOpenForm(Type typeofForm)
    {
        FormCollection fc = Application.OpenForms;
        foreach (Form f1 in fc)
            if (f1.GetType() == typeofForm)
                return f1;

        return null;
    }
    private object CreateNewInstanceOfType(Type typeofAny)
    {
        return Activator.CreateInstance(typeofAny);
    }

    public void ShowMsg(string sMsg)
    {
        lblStatus.Text = sMsg;
        if (lblStatus.ForeColor != SystemColors.ControlText)
            lblStatus.ForeColor = SystemColors.ControlText;
    }

compruebe este enlace :

using System;

public sealed class Singleton
{
   private static volatile Singleton instance;
   private static object syncRoot = new Object();

   private Singleton() {}

   public static Singleton Instance
   {
      get 
      {
         if (instance == null) 
          {
            lock (syncRoot) 
            {
               if (instance == null) 
                  instance = new Singleton();
            }
         }

         return instance;
      }
   }
}

Pruebe este código

Public class MyClass
{
    //Create a variable named 
    public static int count = 0;
    //Then increment count variable in constructor
    MyClass()
    {
        count++;
    }
}

Al crear el objeto para la clase anterior 'MyClass', compruebe el valor de conteo mayor que 1

class AnotherClass
{
    public void Event()
    {
        if(ClassName.Count <= 1)
        {
            ClassName classname=new ClassName();
        }
    }
}

Aquí hay una manera simple de hacerlo.

Compruebe si el formulario es nulo o se ha eliminado. Si eso es cierto, creamos una nueva instancia del formulario.

De lo contrario, solo mostraremos el formulario que ya se está ejecutando.

    Form form;
    private void btnDesktop_Click(object sender, EventArgs e)
    {
        if (form == null || desktop.IsDisposed)
        {
            form = new Form();
            form.Show();
        }
        else
        {
            form.WindowState = FormWindowState.Normal;
        }
    }

Los Singletons no están orientados a objetos. Son simplemente la versión del objeto de las variables globales. Lo que puede hacer es hacer que el constructor de la clase Form sea privado, para que nadie pueda crear uno de estos accidentalmente. Luego llame en reflexión, convierta el ctor a público y asegúrese de crear una única instancia de ella.

Puede verificar los procesos existentes antes de abrir el formulario:

using System.Diagnostics;

bool ApplicationAlreadyStarted()
{
  return Process.GetProcessesByName(Process.GetCurrentProcess.ProcessName).Length == 0;
}

No sé si el método GetProcessesByName se ve afectado por UAC u otras medidas de seguridad.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top