🪟 Dialog Forms 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! 🚀
Creare altre finestre oltre alla principale. Ogni form può avere
controlli diversi e funzionalità specifiche.
Due modi di aprire finestre: Show = non blocca, ShowDialog = blocca
finché l’utente non chiude (modale).
Inviare informazioni da una finestra all’altra usando costruttori
e proprietà pubbliche.
Dialog già pronti di Windows: Apri File, Salva File, Scegli Colore,
Scegli Font. Pronti all’uso!
- ✅ Timer e ProgressBar (Lezione 9)
- ✅ 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.
- 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.
- 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!
- Progetto già ha Form1 (lo rinomineremo in FormLogin)
- Tasto destro sul progetto → Add → Form (Windows Forms)
- Nome:
FormDashboard.cs→ Add - Ora hai 2 form!
- 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”)
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;
}
}
}
}
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);
}
}
}
- App si apre → mostra FormLogin
- Utente inserisce: Username = “admin”, Password = “1234”
- Clicca Login → credenziali corrette ✅
- FormDashboard si apre con “Benvenuto, admin!”
- FormLogin si nasconde (Hide, non Close!)
- Utente clicca Logout → conferma “Sei sicuro?”
- Clicca Yes → Dashboard si chiude
- Evento FormClosed di Dashboard chiude anche FormLogin
- Applicazione termina
📚 Concetti Chiave – Costruttori
// 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(); // 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()!
// 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!
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!
// 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}";
}
public partial class FormPrincipale : Form
{
private List clienti = new List();
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();
}
}
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!
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}");
}
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");
}
Scegli un colore
ColorDialog cd = new ColorDialog();
if (cd.ShowDialog() == DialogResult.OK)
{
Color colore = cd.Color;
this.BackColor = colore;
}
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)!
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 = non blocca
- ShowDialog = blocca (modale)
- Costruttori con parametri
- Proprietà pubbliche
- OpenFileDialog
- SaveFileDialog
- ColorDialog, FontDialog
Hai imparato a creare app multi-finestra! Prossima lezione:
Validazione Avanzata con ErrorProvider, MaskedTextBox e UX professionale! ✨