268 messaggi dal 25 novembre 2010
salve!
dal Form principale posso avviare vari altri form.
vorrei però evitare che si posso aprire più di una volta lo stesso form.
così ad esempio:
        private void causaleEntrataToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FormGCausE fg = new FormGCausE();
            fg.Show();
        }

l'evento o il metodo Show sono bloccati se già esiste una istanza del form FormGCausE .
è possibile?
5.610 messaggi dal 09 febbraio 2002
Contributi
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 -

- So what you're saying is, if we get in trouble, there's no one to help us out?
- I'm afraid not.
- Fantastic!
268 messaggi dal 25 novembre 2010
ciao grazie per la risposta e scusa il ritardo, ma tra vacanze e ritorno al lavoro nn sono ancora riuscito a fare nulla.
appena riesco a metterci la testa faccio una prova e ti dico!

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.
Community
Ultimi messaggi
UTENTI ONLINE
In primo piano

I più letti di oggi

Media
In evidenza
MISC