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!
- Crea i Form
π Procedura:
- Progetto giΓ ha Form1 (lo rinomineremo in FormLogin)
- Tasto destro sul progetto β Add β Form (Windows Forms)
- Nome:
FormDashboard.csβ Add - 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")
- 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;
}
}
}
}
- 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);
}
}
}
- π¬ Come Funziona
π Flusso Completo:
- 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
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!
- 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}";
}
- 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();
}
}
- 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! β¨