Question

Comment éviter plusieurs instances de windows form en c # ?? Je veux seulement une instance du formulaire en cours d'exécution. Parce qu'il y a des chances d'ouvrir le même formulaire à partir de nombreuses pages de ma candidature.

Était-ce utile?

La solution

implémentez le modèle Singleton

un exemple: CodeProject: Simple Singleton Forms (ok, c'est en VB .NET, mais juste pour vous donner un indice)

Autres conseils

Oui, il a un motif singleton,

Code pour créer un objet 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;
     }
 }
 ....
}

Invoke / Show this form,

Form2.GetForm.Show();

Lorsque vous affichez la boîte de dialogue, utilisez simplement .ShowDialog (); au lieu de .Show ();

Une solution que j'ai appliquée à mon projet pour remettre ce formulaire au premier plan est la suivante:

    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 est essentiellement le nom de classe de votre Windows Form et La valeur de retour peut être utilisée pour ne pas créer une nouvelle instance de formulaire.

Si votre système a la possibilité d’afficher le même type de formulaire pour différentes données d’instance, vous pouvez créer un système de vérification qui itère tous les formulaires ouverts existants, recherche un identificateur unique de données d’instance, puis réaffiche tout formulaire trouvé.

par exemple. ayant une classe de formulaire 'CustomerDetails' contenant la propriété publique '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);
    }
}

Nous utilisons également le même mécanisme pour forcer automatiquement l'actualisation de la liaison de données lorsque les données d'un client ont été modifiées et enregistrées.

Voici ma solution dans 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;
    }

vérifiez ce lien :

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

Essayez ce code

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

Lors de la création de l'objet pour la classe ci-dessus 'MyClass', vérifiez la valeur de comptage supérieure à 1

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

Voici un moyen simple de le faire.

Vérifiez si le formulaire est nul ou s'il a été supprimé. Si cela est vrai, nous créons une nouvelle instance du formulaire.

Sinon, nous montrons simplement le formulaire en cours d'exécution.

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

Les singletons ne sont pas orientés objet. Ils sont simplement la version objet des variables globales. Ce que vous pouvez faire est de rendre le constructeur de la classe Form privé, afin que personne ne puisse en créer une par accident. Puis appelez en réflexion, convertissez le ctor en public et assurez-vous de n'en créer qu'une et une seule.

Vous pouvez vérifier les processus existants avant d'ouvrir le formulaire:

using System.Diagnostics;

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

Je ne sais pas si la méthode GetProcessesByName est affectée par le contrôle de compte d'utilisateur ou d'autres mesures de sécurité.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top