Ciao,
potresti "prendere nota" in una variabile che il form di quel tipo è stato aperto e poi svuotare la variabile nel momento in cui quel form viene chiuso.
Quando l'utente richiede l'apertura del form, dovrai controllare il contenuto di quella variabile e aprire un nuovo form solo se era vuota.
private FormGCausE fg = null;
private void causaleEntrataToolStripMenuItem_Click(object sender, EventArgs e)
{
//controllo che la variabile non sia vuota prima di creare un nuovo form
if (fg == null){
fg = new FormGCausE();
//devo ricordarmi di svuotare la variabile quando il form viene chiuso
//perciò sottoscrivo il suo evento .FormClosed e reimposto fg a null
fg.FormClosed += (sender, eventArgs) => fg = null;
fg.Show();
} else {
//se il form già esisteva, allora mi limito a riportarlo in primo piano
fg.Focus();
}
}
Questo codice funziona... però non è granché, vero? Soprattutto perché tu hai tanti form e dovresti ripetere questa roba per ciascuno di essi, il che violerebbe un po' il principio
Don't Repeat Yourself.
Quindi potresti delegare il compito di creare i nuovi form e di invocare il loro metodo .Show() ad un servizio (banalmente può essere una classe statica) che abbia il controllo della situazione e sappia quali forms sono stati aperti e quali no.
Per analogia, dato che siamo in clima festivo, questa classe assumerebbe il ruolo del tizio che tiene il tabellone della tombola e sa in ogni momento quali numeri sono usciti e quali no.
Metti questo codice in un file .cs a parte, nel namespace della tua applicazione. E' una classe che contiene un metodo generico, cioè che può essere invocato passandogli un tipo.
public static class FormService
{
//questo è un dizionario in cui conservo i tipi di form aperti e le loro referenze
private static Dictionary<Type, Form> _formsAperti = new Dictionary<Type, Form>();
//il metodo Show è generico, accetterà qualsiasi tipo T che erediti da Form
//inoltre impongo che T debba avere un costruttore pubblico, affinché se ne possa creare un'istanza
public static bool Show<T>() where T : Form, new()
{
//qui controllo se nel dizionario è già presente un'istanza di quel tipo
if (_formsAperti.ContainsKey(typeof(T)))
{
//Se era presente, allora riporto in primo piano l'istanza già esistente
_formsAperti[typeof(T)].Focus();
//restituisco false, per informare che non ho dovuto creare una nuova istanza
return false;
}
//altrimenti creo una nuova istanza del tipo richiesto
T newform = new T();
//la aggiungo al dizionario
_formsAperti.Add(typeof(T), newform);
//e qui sottoscrivo l'evento FormClosed
//in modo da rimuovere dal dizionario il tipo del form appena chiuso
newform.FormClosed += (sender, e) => _formsAperti.Remove(sender.GetType());
//infine, mostro il nuovo form
newform.Show();
//restituisco true perché voglio informare che una nuova istanza è stata creata
//in realtà potrei modificare questo metodo affinché restituisca l'istanza creata, anziché un booleano
//nel caso dovessi fare altro lavoro col nuovo form, subito dopo l'invocazione di .Show.
return true;
}
}
e all'interno del tuo evento click lo usi così. Vedi che non usi più parola chiave
new perché di creare una nuova istanza se ne occuperà il FormService, e solo se non era già stata creata prima. Tu gli dai solo un "indizio" passandogli il tipo FormGCausE del form che intendi aprire.
private void causaleEntrataToolStripMenuItem_Click(object sender, EventArgs e)
{
FormService.Show<FormGCausE>();
}
ciao
Modificato da BrightSoul il 31 dicembre 2011 12.39 -