Nuova form che si apre

di il
5 risposte

Nuova form che si apre

Spero di aver scritto correttamente il titolo, in caso contrario invito i moderatori modificarlo.

Ho due problemi, uno collegato all'altro.
Ho due form - form1 e form2.
Form1 è la form principale dove si inseriscono e modificano i dati.
Form2 è la form dove l'utente visualizza in un DataGridView tutti i dati registrati, sceglie quello che gli serve e con un doppio click ritorna alla form1, passando i dati a Form1.
Funziona tutto.
Il problema è che quando cerco di tornare a form1 il compilatore mi apre un'altra form1 identica a quella già aperta, col risultato di ritrovarmi due form1 aperte.
L'evento per passare da form2 a form1 è un double_click del DataGridView e il codice è questo:

Prima scrivevo:

private void dgvUser_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        { 
        	Form1 f1 = new Form1()
        	         
                f1.txtUserId.Text = this.dgvUser.CurrentRow.Cells[0].Value.ToString();
                f1.txtName.Text = this.dgvUser.CurrentRow.Cells[1].Value.ToString();
                f1.txtAge.Text = this.dgvUser.CurrentRow.Cells[2].Value.ToString();
                
                f1.show();
            }
Dopo ho dichiarato la variabile Form1 ; e dopo ancora Static Form1 e ho modificato il codice così (non so perché mi mette le faccine):
private void dgvUser_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
        {
            if (f1 is null)
            {
                f1 = new Form1();
            }
            else
            {
                f1.txtUserId.Text = this.dgvUser.CurrentRow.Cells[0].Value.ToString();
                f1.txtName.Text = this.dgvUser.CurrentRow.Cells[1].Value.ToString();
                f1.txtAge.Text = this.dgvUser.CurrentRow.Cells[2].Value.ToString();
            }  
            f1.Show();
       }
Ma le cose non sono cambiate.
Inoltre, se aggiungo la riga this.Close(), dopo .Show(), Form2 non mi passa i valori selezionati, mentre se rimane aperta sì.
Le domande sono: come faccio a non aprire una nuova identica form? E come faccio a passare i dati da Form2 a Form1 anche se chiudo Form2?

5 Risposte

  • Re: Nuova form che si apre

    Non è meglio usare .showDialog() per queste operazioni?
  • Re: Nuova form che si apre

    Https://docs.microsoft.com/it-it/dotnet/api/system.windows.forms.form.showdialog?view=netcore-3.1
    
    public void ShowMyDialogBox()
    {
       Form2 testDialog = new Form2();
    
       // Show testDialog as a modal dialog and determine if DialogResult = OK.
       if (testDialog.ShowDialog(this) == DialogResult.OK)
       {
          // Read the contents of testDialog's TextBox.
          this.txtResult.Text = testDialog.TextBox1.Text;
       }
       else
       {
          this.txtResult.Text = "Cancelled";
       }
       testDialog.Dispose();
    }
    
  • Re: Nuova form che si apre

    Ho trovato come non far aprire più volte la stessa form. Nel caso potesse interessare a qualcuno di seguito vi metto il codice.
    Abbiamo sempre due form - Form1 e Form2.
    private void button1_Click(object sender, EventArgs e)
            {
                bool isOpen = false;
    
                foreach(Form f in Application.OpenForms)
                {
                    if(f.Text == "Form2")
                    {
                        isOpen = true;
                        f.BringToFront();
                        break;
                    }
                }
    
                if(isOpen == false)
                {
                    Form2 f2 = new Form2();
                    f2.Show();
                }            
            }
    Ragionandoci ero arrivato alla dichiarazione della variabile bool, ma poi mi ero bloccato. Al foreach non ci sarei mai arrivato.
  • Re: Nuova form che si apre

    Fabriziog ha scritto:


    Il problema è che quando cerco di tornare a form1 il compilatore mi apre un'altra form1 identica a quella già aperta, col risultato di ritrovarmi due form1 aperte.
    Il problema principale da risolvere è comprendere la differenza tra classe e istanza: .NET non è come il vecchio VB6, e C# è un linguaggio che rispetta i principi della OOP, ossia della programmazione orientata agli oggetti.

    Tutte le volte che fai New() stai creando di fatto un nuovo oggetto. L'identificatore Form1 (nome da cambiare quanto prima, e che deve rispecchiare le finalità della finestra) identifica la classe del Form, ossia il tipo di dato che descrive i comportamenti e le caratteristiche di un ipotetico Form appartenente a questo tipo: prima di usarlo quindi, deve essere istanziato con New(), ma se è necessario fare riferimento sempre allo stesso Form, il riferimento va memorizzato in una variabile e riutilizzato, senza fare di nuovo New(), poiché questo comporterebbe la creazione e l'uso di una "nuova istanza" di Form1, ossia di un nuovo oggetto che si comporta in tutto e per tutto come descritto nella classe di appartenenza ma che si affianca all'istanza già esistente dello stesso tipo, avendo quindi a quel punto due Form uguali.

    Si tratta di un concetto fondamentale senza il quale non è possibile programmare in modo sicuro, tranquillo e proficuo con C#, a meno di non introdurre escamotage e altri "giri" con codice che mina alle basi la stabilità dell'applicazione, come in questo caso:
    foreach(Form f in Application.OpenForms) {...}
    Nel caso in esame inoltre, è meglio far restituire a Form2 i dati da utilizzare e consentire a Form1 di recuperarli, piuttosto che tentare di impostarli direttamente da Form2: si evità così un riferimento circolare e una dipendenza inutile tra le due finestre, consentendo potenzialmente anche il riuso di Form2 in altri contesti.

    Fai una ricerca sul forum o sul Web e recupera eventualmente un libro che spieghi questi rudimenti per comprenderli al meglio, altrimenti effetti collaterali di questo tipo ne avrai sempre a non finire.

    Ciao!
  • Re: Nuova form che si apre

    Mentre scrivevo è arrivato il post di Alka, vado alla conclusione senza premessa.
    Il codice che hai scritto apre un nuovo form, nel quale dovrai ricaricare tutti i dati.
    Se come immagino i due forms li hai aggiunti da progettazione e ti occorrono sempre gli stessi, puoi impedire all'utente di chiudere il Form2 aggiuggendo l'evento FormClosing:
    
           private void Form2_FormClosing(object sender, FormClosingEventArgs e)
            {
                e.Cancel = true;
                this.Visible = false;
            }
    
    In questo modo Form2 è sempre attivo in memoria e da Form1 lo puoi rendere visibile o invisibile come vuoi, se l'utente clicca la x su Form2, invece di chiuderlo lo rende invisibile.
Devi accedere o registrarti per scrivere nel forum
5 risposte