Vai al contenuto

Dialog form e comunicazione tra finestre

Crea applicazioni professionali con piΓΉ finestre che comunicano tra loro!.

Cosa Imparerai in Questa Lezione

Fino ad ora hai lavorato con una sola finestra. Oggi scoprirai come creare applicazioni multi-finestra come i programmi professionali: login che apre la dashboard, pulsante "Dettagli" che apre una finestra con info, finestre di conferma personalizzate! πŸš€

✨ Concetti di Questa Lezione

πŸͺŸ Form Secondari

Creare altre finestre oltre alla principale. Ogni form puΓ² avere controlli diversi e funzionalitΓ  specifiche.

πŸ’¬ Show() vs ShowDialog()

Due modi di aprire finestre: Show = non blocca, ShowDialog = blocca finchΓ© l'utente non chiude (modale).

πŸ“‘ Passare Dati tra Form

Inviare informazioni da una finestra all'altra usando costruttori e proprietΓ  pubbliche.

πŸ“‚ Dialog Predefiniti

Dialog giΓ  pronti di Windows: Apri File, Salva File, Scegli Colore, Scegli Font. Pronti all'uso!

πŸ“š Prerequisiti

  • βœ… Timer e ProgressBar
  • βœ… Concetti di variabili e costruttori
  • βœ… Gestione eventi

Show() vs ShowDialog(): Differenze Cruciali

Show() - Non Modale

Comportamento:

La finestra si apre ma NON blocca l'app principale. L'utente puΓ² cliccare su entrambe le finestre.

πŸ’‘ Quando usarlo:

  • Finestre di aiuto
  • Calcolatrice separata
  • Palette strumenti
  • Dashboard multi-finestra
Form2 finestra = new Form2();
finestra.Show();
// Il codice continua subito!

ShowDialog() - Modale

Comportamento:

La finestra si apre e BLOCCA tutto il resto. Devi chiuderla prima di usare l'app principale.

πŸ’‘ Quando usarlo:

  • Login obbligatorio
  • Conferme importanti
  • Impostazioni da salvare
  • Form di inserimento dati
Form2 finestra = new Form2();
finestra.ShowDialog();
// Il codice aspetta qui finchΓ© chiudi!

Esercizio 1: Sistema di Login

Obiettivo

Crea un sistema con 2 finestre: una per il login e una per la dashboard principale. Solo con credenziali corrette si apre la dashboard!

  1. Crea i Form

πŸ“ Procedura:

  1. Progetto giΓ  ha Form1 (lo rinomineremo in FormLogin)
  2. Tasto destro sul progetto β†’ Add β†’ Form (Windows Forms)
  3. Nome: FormDashboard.cs β†’ Add
  4. Ora hai 2 form!

🎨 FormLogin (Form1):

  • Label: "Username:"
  • TextBox: txt_username
  • Label: "Password:"
  • TextBox: txt_password (PasswordChar = '*')
  • Button: btn_login (Text = "πŸ”“ Login")
  • Label: lbl_errore (Text = "", ForeColor = Red)

🎨 FormDashboard:

  • Label: lbl_benvenuto (Text = "Benvenuto, [Nome]!", Font grande)
  • Label: "Dashboard Principale"
  • Button: btn_logout (Text = "πŸ”’ Logout")
  1. Codice FormLogin (Form1.cs)

FormLogin.cs

using System;
using System.Windows.Forms;

namespace SistemaLogin
{
    public partial class Form1 : Form
    {
        // Credenziali hardcoded (in app reale: database!)
        private const string USERNAME_CORRETTO = "admin";
        private const string PASSWORD_CORRETTA = "1234";

        public Form1()
        {
            InitializeComponent();

            // Imposta PasswordChar per nascondere password
            txt_password.PasswordChar = '●';

            // Permetti login con INVIO
            this.AcceptButton = btn_login;
        }

        // ═══════════════════════════════════════════
        // PULSANTE LOGIN
        // ═══════════════════════════════════════════
        private void btn_login_Click(object sender, EventArgs e)
        {
            // Prendi le credenziali inserite
            string username = txt_username.Text.Trim();
            string password = txt_password.Text;

            // Validazione base
            if (string.IsNullOrWhiteSpace(username))
            {
                lbl_errore.Text = "❌ Inserisci lo username!";
                txt_username.Focus();
                return;
            }

            if (string.IsNullOrWhiteSpace(password))
            {
                lbl_errore.Text = "❌ Inserisci la password!";
                txt_password.Focus();
                return;
            }

            // Verifica credenziali
            if (username == USERNAME_CORRETTO && password == PASSWORD_CORRETTA)
            {
                // βœ… LOGIN RIUSCITO!

                // Crea e mostra la dashboard
                FormDashboard dashboard = new FormDashboard(username);
                dashboard.Show();

                // NASCONDI il form di login (non chiudere!)
                this.Hide();

                // Quando chiude la dashboard, chiudi anche login
                dashboard.FormClosed += (s, args) => this.Close();
            }
            else
            {
                // ❌ LOGIN FALLITO
                lbl_errore.Text = "❌ Username o password errati!";
                txt_password.Clear();
                txt_password.Focus();

                // Bonus: animazione shake
                this.Left -= 10;
                System.Threading.Thread.Sleep(50);
                this.Left += 20;
                System.Threading.Thread.Sleep(50);
                this.Left -= 10;
            }
        }
    }
}
  1. Codice FormDashboard.cs

FormDashboard.cs

using System;
using System.Windows.Forms;

namespace SistemaLogin
{
    public partial class FormDashboard : Form
    {
        private string nomeUtente;

        // ═══════════════════════════════════════════
        // COSTRUTTORE: Riceve il nome utente dal login
        // ═══════════════════════════════════════════
        public FormDashboard(string username)
        {
            InitializeComponent();

            // Salva il nome utente
            this.nomeUtente = username;

            // Personalizza il benvenuto
            lbl_benvenuto.Text = $"πŸ‘‹ Benvenuto, {nomeUtente}!";

            // Imposta titolo finestra
            this.Text = $"Dashboard - {nomeUtente}";
        }

        // ═══════════════════════════════════════════
        // PULSANTE LOGOUT
        // ═══════════════════════════════════════════
        private void btn_logout_Click(object sender, EventArgs e)
        {
            DialogResult risultato = MessageBox.Show(
                "Sei sicuro di voler uscire?",
                "Conferma Logout",
                MessageBoxButtons.YesNo,
                MessageBoxIcon.Question);

            if (risultato == DialogResult.Yes)
            {
                // Chiudi la dashboard
                // Questo farΓ  chiudere anche il FormLogin
                this.Close();
            }
        }

        // ═══════════════════════════════════════════
        // EVENTO: Quando la finestra si chiude
        // ═══════════════════════════════════════════
        protected override void OnFormClosing(FormClosingEventArgs e)
        {
            base.OnFormClosing(e);

            MessageBox.Show($"Arrivederci, {nomeUtente}!",
                          "Logout",
                          MessageBoxButtons.OK,
                          MessageBoxIcon.Information);
        }
    }
}
  1. 🎬 Come Funziona

πŸ“‹ Flusso Completo:

  1. App si apre β†’ mostra FormLogin
  2. Utente inserisce: Username = "admin", Password = "1234"
  3. Clicca Login β†’ credenziali corrette βœ…
  4. FormDashboard si apre con "Benvenuto, admin!"
  5. FormLogin si nasconde (Hide, non Close!)
  6. Utente clicca Logout β†’ conferma "Sei sicuro?"
  7. Clicca Yes β†’ Dashboard si chiude
  8. Evento FormClosed di Dashboard chiude anche FormLogin
  9. Applicazione termina

Concetti Chiave - Costruttori

Costruttore con Parametri

Permette di passare dati quando crei un form

// Nel form che riceve i dati
public FormDashboard(string username)
{
    InitializeComponent();
    this.nomeUtente = username;
}

// Nel form che apre
FormDashboard dash = new FormDashboard("Mario");
dash.Show();

this.Hide() vs this.Close()

Nascondere vs chiudere una finestra

this.Hide();   // Nasconde ma il form esiste ancora in memoria
this.Show();   // Mostra di nuovo un form nascosto

this.Close();  // Chiude e DISTRUGGE il form
// Dopo Close() non puoi piΓΉ fare Show()!

AcceptButton

Pulsante che si "clicca" quando premi INVIO

// Nel costruttore del form
this.AcceptButton = btn_login;

// Ora premere INVIO = cliccare btn_login

DialogResult: Sapere Cosa Ha Scelto l'Utente

Quando usi ShowDialog(), puoi sapere quale pulsante ha cliccato l'utente: OK, Cancel, Yes, No, ecc. Usa la proprietΓ  DialogResult!

🎯 Valori Disponibili

DialogResult.OK          // Pulsante OK
DialogResult.Cancel      // Pulsante Cancel
DialogResult.Yes         // Pulsante Yes
DialogResult.No          // Pulsante No
DialogResult.Abort       // Pulsante Abort
DialogResult.Retry       // Pulsante Retry
DialogResult.Ignore      // Pulsante Ignore

Esercizio 2: Gestionale Clienti con Dettagli

Obiettivo

Lista clienti. Clicchi "Dettagli" β†’ si apre finestra con tutte le info del cliente!

  1. Crea Classe Cliente
// Classe per rappresentare un cliente
public class Cliente
{
    public string Nome { get; set; }
    public string Cognome { get; set; }
    public string Email { get; set; }
    public string Telefono { get; set; }
    public string Citta { get; set; }

    public string NomeCompleto => $"{Nome} {Cognome}";
}
  1. Form Principale (con ListBox)
public partial class FormPrincipale : Form
{
    private List<Cliente> clienti = new List<Cliente>();

    public FormPrincipale()
    {
        InitializeComponent();
        AggiungiClientiDiEsempio();
        CaricaLista();
    }

    private void AggiungiClientiDiEsempio()
    {
        clienti.Add(new Cliente
        {
            Nome = "Mario", Cognome = "Rossi",
            Email = "mario@email.it", Telefono = "333-1234567",
            Citta = "Roma"
        });

        clienti.Add(new Cliente
        {
            Nome = "Laura", Cognome = "Bianchi",
            Email = "laura@email.it", Telefono = "333-7654321",
            Citta = "Milano"
        });
    }

    private void CaricaLista()
    {
        lst_clienti.Items.Clear();
        foreach (Cliente c in clienti)
        {
            lst_clienti.Items.Add(c.NomeCompleto);
        }
    }

    // ═══════════════════════════════════════════
    // PULSANTE: Mostra Dettagli
    // ═══════════════════════════════════════════
    private void btn_dettagli_Click(object sender, EventArgs e)
    {
        if (lst_clienti.SelectedIndex == -1)
        {
            MessageBox.Show("Seleziona un cliente!", "Attenzione",
                          MessageBoxButtons.OK, MessageBoxIcon.Warning);
            return;
        }

        // Prendi il cliente selezionato
        Cliente clienteSelezionato = clienti[lst_clienti.SelectedIndex];

        // Apri finestra dettagli (MODALE)
        FormDettagliCliente formDettagli = new FormDettagliCliente(clienteSelezionato);
        formDettagli.ShowDialog();
    }
}
  1. FormDettagliCliente (Form Secondario)
public partial class FormDettagliCliente : Form
{
    private Cliente cliente;

    public FormDettagliCliente(Cliente c)
    {
        InitializeComponent();

        this.cliente = c;

        // Mostra i dettagli
        MostraDettagli();
    }

    private void MostraDettagli()
    {
        lbl_nome.Text = $"Nome: {cliente.Nome}";
        lbl_cognome.Text = $"Cognome: {cliente.Cognome}";
        lbl_email.Text = $"Email: {cliente.Email}";
        lbl_telefono.Text = $"Telefono: {cliente.Telefono}";
        lbl_citta.Text = $"CittΓ : {cliente.Citta}";

        this.Text = $"Dettagli - {cliente.NomeCompleto}";
    }

    private void btn_chiudi_Click(object sender, EventArgs e)
    {
        this.Close();
    }
}

Dialog Predefiniti di Windows

Windows ha giΓ  pronti dei dialog per operazioni comuni! Non devi crearli da zero!

πŸ“‚ OpenFileDialog

Finestra "Apri File"

OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "File di testo|*.txt|Tutti i file|*.*";
ofd.Title = "Seleziona un file";

if (ofd.ShowDialog() == DialogResult.OK)
{
    string percorso = ofd.FileName;
    MessageBox.Show($"Hai scelto: {percorso}");
}

πŸ’Ύ SaveFileDialog

Finestra "Salva File"

SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "File di testo|*.txt";
sfd.DefaultExt = "txt";
sfd.FileName = "documento";

if (sfd.ShowDialog() == DialogResult.OK)
{
    string percorso = sfd.FileName;
    File.WriteAllText(percorso, "Contenuto");
}

🎨 ColorDialog

Scegli un colore

ColorDialog cd = new ColorDialog();

if (cd.ShowDialog() == DialogResult.OK)
{
    Color colore = cd.Color;
    this.BackColor = colore;
}

πŸ”€ FontDialog

Scegli un font

FontDialog fd = new FontDialog();

if (fd.ShowDialog() == DialogResult.OK)
{
    Font font = fd.Font;
    lbl_testo.Font = font;
}

Esercizio 3: Mini Editor di Testo

Obiettivo

Editor con menu File (Nuovo, Apri, Salva) e Formato (Font, Colore)!

EditorTesto.cs (Versione Completa)

using System;
using System.IO;
using System.Windows.Forms;

namespace EditorTesto
{
    public partial class Form1 : Form
    {
        private string percorsoFileCorrente = "";

        public Form1()
        {
            InitializeComponent();
        }

        // ═══════════════════════════════════════════
        // MENU: File β†’ Nuovo
        // ═══════════════════════════════════════════
        private void nuovoToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (!string.IsNullOrEmpty(txt_editor.Text))
            {
                DialogResult ris = MessageBox.Show(
                    "Vuoi salvare le modifiche?",
                    "Nuovo File",
                    MessageBoxButtons.YesNoCancel,
                    MessageBoxIcon.Question);

                if (ris == DialogResult.Yes)
                {
                    SalvaFile();
                }
                else if (ris == DialogResult.Cancel)
                {
                    return;
                }
            }

            txt_editor.Clear();
            percorsoFileCorrente = "";
            this.Text = "Editor - Nuovo file";
        }

        // ═══════════════════════════════════════════
        // MENU: File β†’ Apri
        // ═══════════════════════════════════════════
        private void apriToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "File di testo (*.txt)|*.txt|Tutti i file (*.*)|*.*";
            ofd.Title = "Apri file";

            if (ofd.ShowDialog() == DialogResult.OK)
            {
                try
                {
                    txt_editor.Text = File.ReadAllText(ofd.FileName);
                    percorsoFileCorrente = ofd.FileName;
                    this.Text = $"Editor - {Path.GetFileName(ofd.FileName)}";
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"Errore: {ex.Message}", "Errore",
                                  MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        // ═══════════════════════════════════════════
        // MENU: File β†’ Salva
        // ═══════════════════════════════════════════
        private void salvaToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SalvaFile();
        }

        private void SalvaFile()
        {
            if (string.IsNullOrEmpty(percorsoFileCorrente))
            {
                // Prima volta: chiedi dove salvare
                SaveFileDialog sfd = new SaveFileDialog();
                sfd.Filter = "File di testo (*.txt)|*.txt";
                sfd.DefaultExt = "txt";
                sfd.FileName = "documento";

                if (sfd.ShowDialog() == DialogResult.OK)
                {
                    percorsoFileCorrente = sfd.FileName;
                }
                else
                {
                    return;
                }
            }

            try
            {
                File.WriteAllText(percorsoFileCorrente, txt_editor.Text);
                MessageBox.Show("File salvato!", "Successo",
                              MessageBoxButtons.OK, MessageBoxIcon.Information);
                this.Text = $"Editor - {Path.GetFileName(percorsoFileCorrente)}";
            }
            catch (Exception ex)
            {
                MessageBox.Show($"Errore: {ex.Message}", "Errore",
                              MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        // ═══════════════════════════════════════════
        // MENU: Formato β†’ Font
        // ═══════════════════════════════════════════
        private void fontToolStripMenuItem_Click(object sender, EventArgs e)
        {
            FontDialog fd = new FontDialog();
            fd.Font = txt_editor.Font;

            if (fd.ShowDialog() == DialogResult.OK)
            {
                txt_editor.Font = fd.Font;
            }
        }

        // ═══════════════════════════════════════════
        // MENU: Formato β†’ Colore
        // ═══════════════════════════════════════════
        private void coloreToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ColorDialog cd = new ColorDialog();
            cd.Color = txt_editor.ForeColor;

            if (cd.ShowDialog() == DialogResult.OK)
            {
                txt_editor.ForeColor = cd.Color;
            }
        }

        // ═══════════════════════════════════════════
        // MENU: File β†’ Esci
        // ═══════════════════════════════════════════
        private void esciToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }
    }
}

Riepilogo

βœ… Show() vs ShowDialog()

  • Show = non blocca
  • ShowDialog = blocca (modale)

βœ… Passare Dati

  • Costruttori con parametri
  • ProprietΓ  pubbliche

βœ… Dialog Predefiniti

  • OpenFileDialog
  • SaveFileDialog
  • ColorDialog, FontDialog

πŸš€ Prossima Lezione

Hai imparato a creare app multi-finestra! Prossima lezione: Validazione Avanzata con ErrorProvider, MaskedTextBox e UX professionale! ✨