📑 TabControl e DataGridView in Windows Forms
Crea interfacce multi-scheda e visualizza dati in tabelle professionali
🎯 Cosa Imparerai in Questa Lezione
Hai imparato i controlli base di Windows Forms. Ora è il momento di creare
interfacce professionali con più pagine e tabelle di dati!
Pensa a programmi come Excel con le sue schede in basso, o a gestionali
con sezioni diverse. Oggi imparerai a crearli! 🚀
Crea schede multiple come Excel! Ogni scheda può contenere
controlli diversi. Perfetto per organizzare app complesse.
Es: Scheda “Anagrafica” | Scheda “Voti” | Scheda “Statistiche”
Mostra dati in formato tabella come Excel! Colonne, righe,
ordinamento. L’utente può modificare, aggiungere, eliminare.
Es: Tabella studenti con Nome | Cognome | Voto | Classe
Contenitori per organizzare altri controlli. Panel è fisso,
FlowLayoutPanel dispone automaticamente i controlli in fila.
Es: Raggruppare tutti i pulsanti in un Panel in fondo al form
Prima di iniziare, dovresti aver completato:
- ✅ Tutti i controlli base (TextBox, ListBox, ComboBox)
- ✅ Gestione eventi multipli
- ✅ RadioButton e CheckBox
📑 Cos’è il TabControl?
🤔 Analogia della Vita Reale
Hai presente i quaderni con i separatori colorati per dividere
le materie? O un’agenda con schede per mesi diversi?
Il TabControl è esattamente questo: ti permette di creare più “pagine”
nella stessa finestra!
- Excel: Foglio1 | Foglio2 | Foglio3 (in basso)
- Browser: Schede multiple per siti diversi
- Impostazioni Windows: Sistema | Rete | Privacy
- Gestionale Studenti: Anagrafica | Voti | Presenze
- Hai molti controlli da organizzare
- L’app ha sezioni logiche separate
- Vuoi un’interfaccia pulita e ordinata
- Hai solo 2-3 controlli semplici
- Le sezioni sono troppo collegate
- L’utente deve vedere tutto insieme
📝 Esercizio 1: Gestionale Studenti con TabControl
▶ Obiettivo
Creare un’applicazione per gestire studenti con 3 schede diverse:
una per l’anagrafica, una per i voti, e una per le statistiche. Ogni scheda
avrà controlli specifici!
- Creare un TabControl con più schede
- Aggiungere controlli diversi in ogni scheda
- Navigare tra le schede via codice
- Passare dati tra schede diverse
- Trascina un TabControl dalla Toolbox sul form
- Ridimensionalo per occupare quasi tutto il form
- Vedrai 2 schede di default:
tabPage1etabPage2 - Per aggiungere una terza scheda:
- Clicca con il tasto destro sul TabControl
- Seleziona “Add Tab”
- Oppure: vai in Properties → TabPages → clicca … → Add
- Rinomina le schede:
- Seleziona tabPage1 → Properties → Text = “Anagrafica”
- Seleziona tabPage2 → Properties → Text = “Voti”
- Seleziona tabPage3 → Properties → Text = “Statistiche”
📄 SCHEDA 1 – Anagrafica:
- Label: “Nome:”
- TextBox:
txt_nome - Label: “Cognome:”
- TextBox:
txt_cognome - Label: “Classe:”
- ComboBox:
cmb_classe(1A, 2A, 3A, 4A, 5A) - Button:
btn_salva_studente(testo: “Salva Studente”)
📊 SCHEDA 2 – Voti:
- Label: “Materia:”
- TextBox:
txt_materia - Label: “Voto:”
- NumericUpDown:
num_voto(Minimum=1, Maximum=10) - Button:
btn_aggiungi_voto(testo: “Aggiungi Voto”) - ListBox:
lst_voti(per vedere i voti inseriti)
📈 SCHEDA 3 – Statistiche:
- Label:
lbl_media(testo: “Media: –“) - Label:
lbl_voto_max(testo: “Voto Max: –“) - Label:
lbl_voto_min(testo: “Voto Min: –“) - Button:
btn_calcola_statistiche(testo: “Calcola”)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace GestionaleStudenti
{
public partial class Form1 : Form
{
// Lista per memorizzare i voti
private List voti = new List();
// Variabili per i dati studente
private string nomeStudente = "";
private string cognomeStudente = "";
private string classeStudente = "";
public Form1()
{
InitializeComponent();
// Popola la ComboBox delle classi
cmb_classe.Items.AddRange(new string[] { "1A", "2A", "3A", "4A", "5A" });
cmb_classe.SelectedIndex = 0; // Seleziona il primo
}
// ═══════════════════════════════════════════
// SCHEDA 1: SALVA DATI STUDENTE
// ═══════════════════════════════════════════
private void btn_salva_studente_Click(object sender, EventArgs e)
{
// Valida che i campi siano compilati
if (string.IsNullOrWhiteSpace(txt_nome.Text))
{
MessageBox.Show("Inserisci il nome!", "Attenzione",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
txt_nome.Focus();
return;
}
if (string.IsNullOrWhiteSpace(txt_cognome.Text))
{
MessageBox.Show("Inserisci il cognome!", "Attenzione",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
txt_cognome.Focus();
return;
}
// Salva i dati
nomeStudente = txt_nome.Text.Trim();
cognomeStudente = txt_cognome.Text.Trim();
classeStudente = cmb_classe.SelectedItem.ToString();
// Conferma
MessageBox.Show($"Studente salvato:\n{cognomeStudente} {nomeStudente}\nClasse: {classeStudente}",
"Successo",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
// NAVIGA AUTOMATICAMENTE ALLA SCHEDA VOTI
tabControl1.SelectedIndex = 1; // 0=Anagrafica, 1=Voti, 2=Statistiche
}
// ═══════════════════════════════════════════
// SCHEDA 2: AGGIUNGI VOTO
// ═══════════════════════════════════════════
private void btn_aggiungi_voto_Click(object sender, EventArgs e)
{
// Controlla che ci sia uno studente salvato
if (string.IsNullOrEmpty(nomeStudente))
{
MessageBox.Show("Prima salva i dati dello studente nella scheda Anagrafica!",
"Attenzione",
MessageBoxButtons.OK,
MessageBoxIcon.Warning);
// Torna alla scheda Anagrafica
tabControl1.SelectedIndex = 0;
return;
}
// Valida materia
if (string.IsNullOrWhiteSpace(txt_materia.Text))
{
MessageBox.Show("Inserisci la materia!", "Attenzione",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
txt_materia.Focus();
return;
}
// Prendi il voto
double voto = (double)num_voto.Value;
// Aggiungi alla lista
voti.Add(voto);
// Mostra nella ListBox
lst_voti.Items.Add($"{txt_materia.Text}: {voto}");
// Pulisci i campi per il prossimo inserimento
txt_materia.Clear();
num_voto.Value = 6; // Reset a 6
txt_materia.Focus();
}
// ═══════════════════════════════════════════
// SCHEDA 3: CALCOLA STATISTICHE
// ═══════════════════════════════════════════
private void btn_calcola_statistiche_Click(object sender, EventArgs e)
{
// Controlla che ci siano voti
if (voti.Count == 0)
{
MessageBox.Show("Non ci sono voti da calcolare!\nAggiungi dei voti nella scheda Voti.",
"Attenzione",
MessageBoxButtons.OK,
MessageBoxIcon.Warning);
// Vai alla scheda Voti
tabControl1.SelectedIndex = 1;
return;
}
// Calcola statistiche usando LINQ
double media = voti.Average();
double votoMax = voti.Max();
double votoMin = voti.Min();
// Mostra risultati
lbl_media.Text = $"Media: {media:F2}"; // F2 = 2 decimali
lbl_voto_max.Text = $"Voto Max: {votoMax}";
lbl_voto_min.Text = $"Voto Min: {votoMin}";
// Cambia colore in base alla media
if (media >= 6)
{
lbl_media.ForeColor = Color.Green;
}
else
{
lbl_media.ForeColor = Color.Red;
}
}
}
}
1️⃣ Scheda Anagrafica:
- L’utente inserisce: Nome = “Mario”, Cognome = “Rossi”, Classe = “3A”
- Clicca “Salva Studente”
- L’app passa automaticamente alla scheda Voti
2️⃣ Scheda Voti:
- Inserisce: Materia = “Matematica”, Voto = 8
- Clicca “Aggiungi Voto” → appare “Matematica: 8” nella ListBox
- Inserisce: Materia = “Italiano”, Voto = 7
- Inserisce: Materia = “Inglese”, Voto = 9
- Totale: 3 voti inseriti
3️⃣ Scheda Statistiche:
- Clicca “Calcola”
- Media: 8.00 (verde perché ≥ 6)
- Voto Max: 9
- Voto Min: 7
📚 Concetti Chiave – TabControl
tabControl1.SelectedIndex = 0; // Prima scheda tabControl1.SelectedIndex = 1; // Seconda scheda tabControl1.SelectedIndex = 2; // Terza scheda // Ottieni l'indice della scheda corrente int schemaCorrente = tabControl1.SelectedIndex;
Listnumeri = new List { 5, 8, 3, 9, 7 }; double media = numeri.Average(); // 6.4 double massimo = numeri.Max(); // 9 double minimo = numeri.Min(); // 3 int conteggio = numeri.Count; // 5 double somma = numeri.Sum(); // 32
string.IsNullOrWhiteSpace("") // true
string.IsNullOrWhiteSpace(" ") // true (solo spazi)
string.IsNullOrWhiteSpace("Mario") // false
string.IsNullOrWhiteSpace(null) // true
📊 Cos’è il DataGridView?
🤔 Pensa a Excel!
Il DataGridView è praticamente una tabella Excel
dentro la tua applicazione! Ha colonne, righe, e puoi aggiungere/modificare/eliminare
dati direttamente come in un foglio di calcolo.
- Registro Studenti: Nome | Cognome | Classe | Email | Telefono
- Catalogo Prodotti: Codice | Nome | Prezzo | Quantità | Categoria
- Lista Film: Titolo | Anno | Regista | Durata | Genere
- Elenco Auto: Marca | Modello | Anno | Prezzo | Carburante
- ✅ Visualizza molti dati in poco spazio
- ✅ L’utente può ordinare cliccando sulle colonne
- ✅ Supporta modifica diretta delle celle
- ✅ Puoi aggiungere/rimuovere righe facilmente
- ✅ Selezione multipla di righe
- ✅ Scrollbar automatici quando ci sono molti dati
📚 Esercizio 2: Registro Libri con DataGridView
▶ Obiettivo
Creare un’applicazione per gestire una biblioteca personale.
I libri vengono mostrati in una tabella dove puoi aggiungere, rimuovere e
modificare i libri direttamente!
- DataGridView:
dgv_libri- Ridimensionalo per occupare la maggior parte del form
- Properties → Dock = Fill (riempie tutto lo spazio)
- Panel (in fondo con Dock = Bottom) contenente:
- TextBox:
txt_titolo(placeholder: “Titolo”) - TextBox:
txt_autore(placeholder: “Autore”) - NumericUpDown:
num_anno(Minimum=1900, Maximum=2025) - TextBox:
txt_genere(placeholder: “Genere”) - Button:
btn_aggiungi(testo: “Aggiungi Libro”) - Button:
btn_rimuovi(testo: “Rimuovi Selezionato”)
- TextBox:
using System;
using System.Windows.Forms;
namespace RegistroLibri
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
// Inizializza il DataGridView
ImpostaDataGridView();
}
// ═══════════════════════════════════════════
// SETUP INIZIALE: Crea le colonne
// ═══════════════════════════════════════════
private void ImpostaDataGridView()
{
// Pulisci colonne esistenti (se ci sono)
dgv_libri.Columns.Clear();
// Aggiungi colonne manualmente
dgv_libri.Columns.Add("Titolo", "Titolo");
dgv_libri.Columns.Add("Autore", "Autore");
dgv_libri.Columns.Add("Anno", "Anno");
dgv_libri.Columns.Add("Genere", "Genere");
// Imposta larghezza colonne
dgv_libri.Columns["Titolo"].Width = 250;
dgv_libri.Columns["Autore"].Width = 200;
dgv_libri.Columns["Anno"].Width = 80;
dgv_libri.Columns["Genere"].Width = 150;
// Impostazioni visualizzazione
dgv_libri.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
dgv_libri.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dgv_libri.MultiSelect = false; // Seleziona una riga alla volta
dgv_libri.AllowUserToAddRows = false; // Nascondi riga vuota in fondo
// Aggiungi alcuni libri di esempio
AggiungiLibriDiEsempio();
}
// ═══════════════════════════════════════════
// AGGIUNGI LIBRI DI ESEMPIO ALL'AVVIO
// ═══════════════════════════════════════════
private void AggiungiLibriDiEsempio()
{
dgv_libri.Rows.Add("Il Signore degli Anelli", "J.R.R. Tolkien", 1954, "Fantasy");
dgv_libri.Rows.Add("1984", "George Orwell", 1949, "Distopico");
dgv_libri.Rows.Add("Harry Potter e la Pietra Filosofale", "J.K. Rowling", 1997, "Fantasy");
}
// ═══════════════════════════════════════════
// PULSANTE: Aggiungi Nuovo Libro
// ═══════════════════════════════════════════
private void btn_aggiungi_Click(object sender, EventArgs e)
{
// Validazione campi obbligatori
if (string.IsNullOrWhiteSpace(txt_titolo.Text))
{
MessageBox.Show("Inserisci il titolo del libro!", "Attenzione",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
txt_titolo.Focus();
return;
}
if (string.IsNullOrWhiteSpace(txt_autore.Text))
{
MessageBox.Show("Inserisci l'autore!", "Attenzione",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
txt_autore.Focus();
return;
}
// Prendi i dati dai controlli
string titolo = txt_titolo.Text.Trim();
string autore = txt_autore.Text.Trim();
int anno = (int)num_anno.Value;
string genere = txt_genere.Text.Trim();
// Se genere è vuoto, metti "Non specificato"
if (string.IsNullOrWhiteSpace(genere))
{
genere = "Non specificato";
}
// AGGIUNGI LA RIGA AL DATAGRIDVIEW
dgv_libri.Rows.Add(titolo, autore, anno, genere);
// Pulisci i campi per il prossimo inserimento
txt_titolo.Clear();
txt_autore.Clear();
num_anno.Value = DateTime.Now.Year; // Anno corrente
txt_genere.Clear();
txt_titolo.Focus(); // Rimetti focus sul titolo
// Messaggio di conferma
MessageBox.Show($"Libro '{titolo}' aggiunto con successo!",
"Successo",
MessageBoxButtons.OK,
MessageBoxIcon.Information);
}
// ═══════════════════════════════════════════
// PULSANTE: Rimuovi Libro Selezionato
// ═══════════════════════════════════════════
private void btn_rimuovi_Click(object sender, EventArgs e)
{
// Controlla che ci sia una riga selezionata
if (dgv_libri.SelectedRows.Count == 0)
{
MessageBox.Show("Seleziona un libro da rimuovere!", "Attenzione",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
// Prendi la riga selezionata
DataGridViewRow rigaSelezionata = dgv_libri.SelectedRows[0];
// Prendi il titolo per la conferma
string titolo = rigaSelezionata.Cells["Titolo"].Value.ToString();
// Chiedi conferma
DialogResult risultato = MessageBox.Show(
$"Sei sicuro di voler eliminare '{titolo}'?",
"Conferma Eliminazione",
MessageBoxButtons.YesNo,
MessageBoxIcon.Question);
if (risultato == DialogResult.Yes)
{
// RIMUOVI LA RIGA
dgv_libri.Rows.Remove(rigaSelezionata);
MessageBox.Show("Libro rimosso!", "Successo",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
// ═══════════════════════════════════════════
// EVENTO: Doppio Click su una Riga
// ═══════════════════════════════════════════
private void dgv_libri_CellDoubleClick(object sender, DataGridViewCellEventArgs e)
{
// Ignora se clicchi sull'header
if (e.RowIndex < 0) return;
// Prendi la riga cliccata
DataGridViewRow riga = dgv_libri.Rows[e.RowIndex];
// Mostra i dettagli del libro
string dettagli = $"DETTAGLI LIBRO:\n\n" +
$"Titolo: {riga.Cells["Titolo"].Value}\n" +
$"Autore: {riga.Cells["Autore"].Value}\n" +
$"Anno: {riga.Cells["Anno"].Value}\n" +
$"Genere: {riga.Cells["Genere"].Value}";
MessageBox.Show(dettagli, "Dettagli Libro",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}
- btn_aggiungi:
- Event: Click
- Handler: btn_aggiungi_Click
- btn_rimuovi:
- Event: Click
- Handler: btn_rimuovi_Click
- dgv_libri:
- Event: CellDoubleClick
- Handler: dgv_libri_CellDoubleClick
📚 Concetti Chiave - DataGridView
// Sintassi: .Add(name, headerText)
dgv.Columns.Add("Nome", "Nome Completo");
dgv.Columns.Add("Eta", "Età");
// Imposta larghezza
dgv.Columns["Nome"].Width = 200;
// I valori devono essere nello stesso ordine delle colonne
dgv.Rows.Add("Mario Rossi", 25);
dgv.Rows.Add("Luigi Verdi", 30);
// Numero di righe totali
int totaleRighe = dgv.Rows.Count;
// Controlla se c'è una selezione
if (dgv.SelectedRows.Count > 0)
{
// Prendi la prima riga selezionata
DataGridViewRow riga = dgv.SelectedRows[0];
// Leggi valore di una cella
string nome = riga.Cells["Nome"].Value.ToString();
}
// Rimuovi riga selezionata DataGridViewRow riga = dgv.SelectedRows[0]; dgv.Rows.Remove(riga); // Rimuovi per indice dgv.Rows.RemoveAt(0); // Rimuove la prima riga
🚀 Esercizio 3: Dashboard Completa
▶ Obiettivo
Crea un'applicazione professionale che combina TabControl + DataGridView!
Sarà un gestionale prodotti con 3 schede: Catalogo (con tabella), Aggiungi Prodotto, Statistiche.
Questo esercizio integra tutto quello che hai imparato finora!
È un'applicazione di livello professionale.
- DataGridView con colonne: Nome | Prezzo | Quantità | Categoria
- TextBox per ricerca
- Button "Cerca"
- Button "Rimuovi Selezionato"
📝 SCHEDA 2 - Aggiungi Prodotto:
- TextBox: Nome Prodotto
- NumericUpDown: Prezzo (0-10000)
- NumericUpDown: Quantità (0-1000)
- ComboBox: Categoria (Elettronica, Abbigliamento, Alimentari, Sport)
- Button "Aggiungi al Catalogo"
📊 SCHEDA 3 - Statistiche:
- Label: Totale Prodotti
- Label: Valore Totale Magazzino
- Label: Prodotto Più Costoso
- Label: Categoria con Più Prodotti
- Button "Aggiorna Statistiche"
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace DashboardProdotti
{
public partial class Form1 : Form
{
// Classe per rappresentare un prodotto
public class Prodotto
{
public string Nome { get; set; }
public decimal Prezzo { get; set; }
public int Quantita { get; set; }
public string Categoria { get; set; }
public decimal ValoreTotale => Prezzo * Quantita;
}
// Lista prodotti
private List prodotti = new List();
public Form1()
{
InitializeComponent();
// Setup iniziale
ImpostaDataGridView();
ImpostaComboBoxCategorie();
AggiungiProdottiDiEsempio();
}
// ═══════════════════════════════════════════
// SETUP: DataGridView
// ═══════════════════════════════════════════
private void ImpostaDataGridView()
{
dgv_catalogo.Columns.Clear();
dgv_catalogo.Columns.Add("Nome", "Nome Prodotto");
dgv_catalogo.Columns.Add("Prezzo", "Prezzo (€)");
dgv_catalogo.Columns.Add("Quantita", "Quantità");
dgv_catalogo.Columns.Add("Categoria", "Categoria");
dgv_catalogo.AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
dgv_catalogo.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dgv_catalogo.MultiSelect = false;
dgv_catalogo.AllowUserToAddRows = false;
}
// ═══════════════════════════════════════════
// SETUP: ComboBox Categorie
// ═══════════════════════════════════════════
private void ImpostaComboBoxCategorie()
{
cmb_categoria.Items.AddRange(new string[]
{
"Elettronica",
"Abbigliamento",
"Alimentari",
"Sport"
});
cmb_categoria.SelectedIndex = 0;
}
// ═══════════════════════════════════════════
// AGGIUNGI PRODOTTI DI ESEMPIO
// ═══════════════════════════════════════════
private void AggiungiProdottiDiEsempio()
{
prodotti.Add(new Prodotto
{
Nome = "Smartphone",
Prezzo = 599.99m,
Quantita = 15,
Categoria = "Elettronica"
});
prodotti.Add(new Prodotto
{
Nome = "T-Shirt",
Prezzo = 19.99m,
Quantita = 50,
Categoria = "Abbigliamento"
});
prodotti.Add(new Prodotto
{
Nome = "Pasta",
Prezzo = 1.50m,
Quantita = 200,
Categoria = "Alimentari"
});
AggiornaDataGridView();
}
// ═══════════════════════════════════════════
// AGGIORNA IL DATAGRIDVIEW CON I PRODOTTI
// ═══════════════════════════════════════════
private void AggiornaDataGridView()
{
dgv_catalogo.Rows.Clear();
foreach (Prodotto p in prodotti)
{
dgv_catalogo.Rows.Add(
p.Nome,
p.Prezzo.ToString("F2"),
p.Quantita,
p.Categoria
);
}
}
// ═══════════════════════════════════════════
// SCHEDA 2: AGGIUNGI PRODOTTO
// ═══════════════════════════════════════════
private void btn_aggiungi_prodotto_Click(object sender, EventArgs e)
{
// Validazione
if (string.IsNullOrWhiteSpace(txt_nome_prodotto.Text))
{
MessageBox.Show("Inserisci il nome del prodotto!", "Attenzione",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
// Crea nuovo prodotto
Prodotto nuovo = new Prodotto
{
Nome = txt_nome_prodotto.Text.Trim(),
Prezzo = num_prezzo.Value,
Quantita = (int)num_quantita.Value,
Categoria = cmb_categoria.SelectedItem.ToString()
};
// Aggiungi alla lista
prodotti.Add(nuovo);
// Aggiorna DataGridView
AggiornaDataGridView();
// Pulisci campi
txt_nome_prodotto.Clear();
num_prezzo.Value = 0;
num_quantita.Value = 1;
cmb_categoria.SelectedIndex = 0;
// Vai alla scheda Catalogo per vedere il prodotto
tabControl1.SelectedIndex = 0;
MessageBox.Show($"Prodotto '{nuovo.Nome}' aggiunto!", "Successo",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
// ═══════════════════════════════════════════
// SCHEDA 1: CERCA PRODOTTO
// ═══════════════════════════════════════════
private void btn_cerca_Click(object sender, EventArgs e)
{
string termineRicerca = txt_ricerca.Text.Trim().ToLower();
if (string.IsNullOrWhiteSpace(termineRicerca))
{
// Se vuoto, mostra tutti
AggiornaDataGridView();
return;
}
// Filtra prodotti
var prodottiFiltrati = prodotti.Where(p =>
p.Nome.ToLower().Contains(termineRicerca) ||
p.Categoria.ToLower().Contains(termineRicerca)
).ToList();
// Aggiorna DataGridView con i risultati filtrati
dgv_catalogo.Rows.Clear();
foreach (Prodotto p in prodottiFiltrati)
{
dgv_catalogo.Rows.Add(p.Nome, p.Prezzo.ToString("F2"),
p.Quantita, p.Categoria);
}
if (prodottiFiltrati.Count == 0)
{
MessageBox.Show("Nessun prodotto trovato!", "Ricerca",
MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
// ═══════════════════════════════════════════
// SCHEDA 1: RIMUOVI PRODOTTO
// ═══════════════════════════════════════════
private void btn_rimuovi_Click(object sender, EventArgs e)
{
if (dgv_catalogo.SelectedRows.Count == 0)
{
MessageBox.Show("Seleziona un prodotto!", "Attenzione",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
// Prendi la riga selezionata
int indice = dgv_catalogo.SelectedRows[0].Index;
string nome = dgv_catalogo.SelectedRows[0].Cells["Nome"].Value.ToString();
// Conferma
DialogResult ris = MessageBox.Show(
$"Eliminare '{nome}'?",
"Conferma",
MessageBoxButtons.YesNo,
MessageBoxIcon.Question);
if (ris == DialogResult.Yes)
{
// Rimuovi dalla lista
prodotti.RemoveAt(indice);
// Aggiorna DataGridView
AggiornaDataGridView();
}
}
// ═══════════════════════════════════════════
// SCHEDA 3: CALCOLA STATISTICHE
// ═══════════════════════════════════════════
private void btn_aggiorna_statistiche_Click(object sender, EventArgs e)
{
if (prodotti.Count == 0)
{
MessageBox.Show("Nessun prodotto nel catalogo!", "Attenzione",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
// Totale prodotti
int totale = prodotti.Count;
lbl_totale_prodotti.Text = $"Totale Prodotti: {totale}";
// Valore totale magazzino
decimal valoreTotale = prodotti.Sum(p => p.ValoreTotale);
lbl_valore_totale.Text = $"Valore Magazzino: {valoreTotale:C}";
// Prodotto più costoso
Prodotto piuCostoso = prodotti.OrderByDescending(p => p.Prezzo).First();
lbl_prodotto_costoso.Text = $"Più Costoso: {piuCostoso.Nome} (€{piuCostoso.Prezzo:F2})";
// Categoria con più prodotti
var gruppi = prodotti.GroupBy(p => p.Categoria)
.OrderByDescending(g => g.Count())
.First();
lbl_categoria_top.Text = $"Categoria Top: {gruppi.Key} ({gruppi.Count()} prodotti)";
}
}
}
📚 Concetti Avanzati Usati
Listnumeri = new List { 1, 5, 10, 15, 20 }; // Filtra numeri maggiori di 10 var maggioriDi10 = numeri.Where(n => n > 10).ToList(); // Risultato: { 15, 20 } // Filtra stringhe che contengono "a" List nomi = new List { "Mario", "Anna", "Luigi" }; var conA = nomi.Where(n => n.Contains("a")).ToList(); // Risultato: { "Mario", "Anna" }
// Raggruppa prodotti per categoria
var gruppi = prodotti.GroupBy(p => p.Categoria);
foreach (var gruppo in gruppi)
{
Console.WriteLine($"{gruppo.Key}: {gruppo.Count()} prodotti");
}
public class Prodotto
{
public string Nome { get; set; }
public decimal Prezzo { get; set; }
// Proprietà calcolata
public decimal ValoreTotale => Prezzo * Quantita;
}
// Uso
Prodotto p = new Prodotto { Nome = "Telefono", Prezzo = 599 };
Console.WriteLine(p.Nome); // Telefono
📦 Bonus: Panel e Layout
🤔 A Cosa Servono Panel e FlowLayoutPanel?
Sono contenitori per organizzare altri controlli. Invece di
posizionare manualmente 10 pulsanti, li metti in un Panel e sposti solo quello!
Contenitore fisso. I controlli stanno dove li metti.
💡 Quando usarlo:
- Raggruppare pulsanti in fondo al form
- Creare sezioni visive separate
- Con Dock per posizionamento automatico
Dispone i controlli automaticamente in fila, come il testo.
💡 Quando usarlo:
- Toolbar con molti pulsanti
- Gallery di immagini
- Liste di tag/bottoni dinamici
La proprietà Dock attacca un controllo ai bordi del form:
- Dock = Top: Si attacca in alto, occupa tutta la larghezza
- Dock = Bottom: Si attacca in fondo
- Dock = Left/Right: Si attacca a sinistra/destra
- Dock = Fill: Riempie tutto lo spazio rimanente
💡 Esempio pratico: Panel con pulsanti in fondo (Dock=Bottom) + DataGridView che riempie il resto (Dock=Fill)
🎓 Riepilogo: Cosa Hai Imparato
- Creare schede multiple
- Navigare tra schede via codice
- Organizzare app complesse
- Mostrare dati in tabelle
- Aggiungere/rimuovere righe
- Accedere a celle specifiche
- .Where() per filtrare
- .Average(), .Max(), .Min()
- .GroupBy() per raggruppare
- Panel e FlowLayoutPanel
- Proprietà Dock
- Layout professionali
🏋️ Esercizi per Allenarsi
💪 Sfide Progressive
- Crea un TabControl con 2 schede: "Lista Spesa" e "Totale". Nella prima aggiungi prodotti, nella seconda mostra il totale.
- Crea un DataGridView che mostra una lista di film (Titolo, Anno, Genere) con pulsante per aggiungerne di nuovi.
⭐⭐ Livello Medio:
- Gestionale Contatti con TabControl (Anagrafica | Lista | Ricerca) e DataGridView per visualizzare tutti i contatti.
- Registro Presenze: DataGridView con Nome Studente, Data, Presente/Assente. Aggiungi filtro per cercare assenze di uno studente specifico.
⭐⭐⭐ Livello Difficile:
- Crea un Gestionale Videonoleggio completo con: TabControl (Catalogo Film | Prestiti | Statistiche), DataGridView per i film, salvataggio su file CSV.
- Dashboard Aziendale: Dipendenti, Progetti, Assegnazioni. Usa TabControl, DataGridView, e LINQ per statistiche avanzate (chi lavora su cosa, progetti più impegnativi, ecc.).
Hai imparato a organizzare interfacce complesse! Nella prossima lezione scoprirai
Timer e ProgressBar per creare applicazioni che si aggiornano nel
tempo: orologi, cronometri, quiz a tempo e molto altro! ⏱️