Domanda

Come evitare più istanze di Windows Form in c # ?? voglio solo un'istanza del modulo in esecuzione. Perché ci sono possibilità di aprire lo stesso modulo da molte pagine della mia domanda.

È stato utile?

Soluzione

implementa il modello Singleton

un esempio: CodeProject: Simple Singleton Forms (ok, è in VB .NET, ma solo per darti un indizio)

Altri suggerimenti

Sì, ha un modello singleton,

Codice per creare un oggetto 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;
     }
 }
 ....
}

Richiama / Mostra questo modulo,

Form2.GetForm.Show();

Quando visualizzi la finestra di dialogo usa semplicemente .ShowDialog (); invece di .Show();

Una soluzione che ho applicato al mio progetto per riportare questo modulo in primo piano è:

    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 è essenzialmente il nome della classe di Windows Form e il valore restituito può essere utilizzato per non creare una nuova istanza di modulo.

Se il sistema in uso ha la possibilità di mostrare lo stesso tipo di modulo per dati di istanza diversi, è possibile creare un sistema di controllo che esegua l'iterazione di tutti i moduli aperti esistenti, cercando un identificatore di dati di istanza univoco e quindi visualizzare nuovamente qualsiasi modulo trovato.

es. con una classe di modulo "CustomerDetails" che contiene una proprietà pubblica "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);
    }
}

Utilizziamo anche lo stesso meccanismo per forzare automaticamente gli aggiornamenti dell'associazione dei dati in cui i dati di un cliente sono stati modificati e salvati.

Ecco la mia soluzione in 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;
    }

controlla questo link :

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

Prova questo codice

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

Durante la creazione dell'oggetto per la classe precedente "MyClass" controlla il valore di conteggio maggiore di 1

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

Ecco un modo semplice per farlo.

Controlla se il modulo è nullo o è stato eliminato. Se è vero, creiamo una nuova istanza del modulo.

Altrimenti mostriamo solo il modulo già in esecuzione.

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

I singleton non sono orientati agli oggetti. Sono semplicemente la versione oggetto delle variabili globali. Quello che puoi fare è rendere privato il costruttore della classe Form, in modo che nessuno possa accidentalmente crearne uno. Quindi chiama in riflessione, converti il ??ctor in pubblico e assicurati di crearne una e una sola istanza.

Puoi verificare i processi esistenti prima di aprire il modulo:

using System.Diagnostics;

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

Non so se il metodo GetProcessesByName è interessato dall'UAC o da altre misure di sicurezza.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top