ListBox e ComboBox: Teoria e Pratica
Gestisci elenchi di dati con interfacce professionali
🎯 Cosa Imparerai in Questa Lezione
Hai già imparato a raccogliere un singolo dato alla volta con TextBox.
Ma cosa succede quando devi gestire elenchi di elementi?
Prodotti in un inventario, servizi di un hotel, task da completare…
Qui entrano in gioco ListBox e ComboBox: i controlli
più potenti per gestire liste di dati!
Inserisci UN nome alla volta: “Mario”
Gestisci MOLTI nomi: Mario, Luigi, Anna, Sara…
- ✅ ListBox: Lista visibile di elementi (vedi tutti, selezioni uno o più)
- ✅ ComboBox: Menu a tendina (risparmia spazio, selezioni solo uno)
- ✅ List<string>: Lista dinamica che può crescere
- ✅ foreach: Scorrere tutti gli elementi di una lista
🤔 ListBox vs ComboBox: Qual è la Differenza?
📋 ListBox
TUTTI GLI ELEMENTI VISIBILI
□ Mela
■ Banana
□ Arancia
□ Pera
□ Kiwi
- Lista prodotti inventario
- Elenco servizi disponibili
- Task da completare
- File da processare
- Vedi subito tutti gli elementi
- Puoi selezionarne più di uno
- Ideale per liste lunghe con scrollbar
🔽 ComboBox
MENU A TENDINA
Abbigliamento ▼
Abbigliamento
Detersivi
Casa
Alimentari
Sport
- Categorie prodotto
- Tipi di camera hotel
- Priorità task (Bassa/Media/Alta)
- Elenchi con poche opzioni
- Occupa poco spazio
- Elegante per poche opzioni
- Perfetta per categorizzazioni
ListBox = Lista completa visibile (come un menu ristorante aperto)
ComboBox = Menu compatto (come un menu a tendina del telefono)
📋 Proprietà e Metodi Fondamentali
🔑 Proprietà Principali
| Proprietà | Cosa Rappresenta | Esempio ListBox | Esempio ComboBox |
|---|---|---|---|
| Items | La collezione di tutti gli elementi nella lista | lstProdotti.Items |
cmbCategoria.Items |
| SelectedItem | L’elemento attualmente selezionato | lstProdotti.SelectedItem |
cmbCategoria.SelectedItem |
| SelectedIndex | La posizione dell’elemento selezionato (0=primo) | lstProdotti.SelectedIndex |
cmbCategoria.SelectedIndex |
| Text | Il testo dell’elemento selezionato | lstProdotti.Text |
cmbCategoria.Text |
⚡ Metodi Principali
| Metodo | Cosa Fa | Sintassi |
|---|---|---|
| Items.Add() | Aggiunge un elemento alla fine della lista | lstProdotti.Items.Add("Mela"); |
| Items.Remove() | Rimuove un elemento specifico | lstProdotti.Items.Remove("Mela"); |
| Items.RemoveAt() | Rimuove l’elemento in una posizione specifica | lstProdotti.Items.RemoveAt(0); |
| Items.Clear() | Rimuove TUTTI gli elementi | lstProdotti.Items.Clear(); |
| Items.Insert() | Inserisce un elemento in una posizione specifica | lstProdotti.Items.Insert(0, "Banana"); |
Quando nessun elemento è selezionato, SelectedIndex vale -1.
Devi sempre controllare questo valore prima di usare SelectedItem!
// ❌ SBAGLIATO - può crashare!
string prodotto = lstProdotti.SelectedItem.ToString();
// ✅ CORRETTO - controlla prima
if (lstProdotti.SelectedIndex != -1)
{
string prodotto = lstProdotti.SelectedItem.ToString();
MessageBox.Show($"Hai selezionato: {prodotto}");
}
else
{
MessageBox.Show("Seleziona un prodotto prima!");
}
📦 Teoria: List<string> – La Lista Dinamica
🤔 Perché Usare una List<string>?
La ListBox mostra gli elementi all’utente, ma dove li memorizzi nel codice?
Qui entra in gioco List<string>: una lista che può crescere
dinamicamente senza limiti!
Puoi aggiungere infiniti oggetti, e lo scaffale si allunga automaticamente!
// Devi dichiarare la dimensione SUBITO string[] frutti = new string[3]; frutti[0] = "Mela"; frutti[1] = "Banana"; frutti[2] = "Arancia"; // Non puoi aggiungerne altri!
// Lista vuota che può crescere
List<string> frutti = new List<string>();
frutti.Add("Mela");
frutti.Add("Banana");
frutti.Add("Arancia");
frutti.Add("Pera"); // Continua all'infinito!
⚡ Metodi Principali di List<string>
// 1️⃣ CREARE una lista vuota
List<string> prodotti = new List<string>();
// 2️⃣ AGGIUNGERE elementi
prodotti.Add("Laptop");
prodotti.Add("Mouse");
prodotti.Add("Tastiera");
// 3️⃣ RIMUOVERE elemento specifico
prodotti.Remove("Mouse"); // Rimuove "Mouse"
// 4️⃣ RIMUOVERE elemento per posizione
prodotti.RemoveAt(0); // Rimuove il primo (Laptop)
// 5️⃣ VERIFICARE se contiene un elemento
if (prodotti.Contains("Tastiera"))
{
MessageBox.Show("Abbiamo tastiere!");
}
// 6️⃣ CONTARE gli elementi
int quantità = prodotti.Count; // Quanti prodotti?
// 7️⃣ PULIRE tutta la lista
prodotti.Clear(); // Rimuove tutto!
La best practice è usare una List<string> per memorizzare i dati,
e poi “sincronizzarla” con la ListBox quando cambia:
// Lista dati (dietro le quinte)
private List<string> listaProdotti = new List<string>();
// Metodo per aggiungere prodotto
private void AggiungiProdotto(string prodotto)
{
// 1. Aggiungi alla List
listaProdotti.Add(prodotto);
// 2. Aggiorna la ListBox
AggiornaListBox();
}
// Metodo per sincronizzare ListBox con List
private void AggiornaListBox()
{
lstProdotti.Items.Clear(); // Pulisci la ListBox
foreach (string prodotto in listaProdotti)
{
lstProdotti.Items.Add(prodotto); // Riempi con i dati aggiornati
}
}
🔄 Teoria: Il Ciclo foreach
🤔 Cos’è il foreach?
Il foreach è un ciclo che scorre automaticamente tutti gli
elementi di una lista, uno per uno. È perfetto per processare tutti i prodotti, tutti i
task, tutti i servizi…
ogni oggetto davanti a te, uno alla volta, senza che tu debba fare nulla!
// foreach (tipo nomeVariabile in collezione)
foreach (string prodotto in listaProdotti)
{
// Qui "prodotto" rappresenta UN elemento alla volta
MessageBox.Show(prodotto);
}
// Esempio pratico:
List<string> frutti = new List<string> { "Mela", "Banana", "Arancia" };
foreach (string frutto in frutti)
{
Console.WriteLine(frutto);
}
// Output:
// Mela
// Banana
// Arancia
// Devi gestire l'indice manualmente
for (int i = 0; i < frutti.Count; i++)
{
string frutto = frutti[i];
Console.WriteLine(frutto);
}
// Automatico, nessun indice!
foreach (string frutto in frutti)
{
Console.WriteLine(frutto);
}
- ✅ Quando devi scorrere TUTTI gli elementi
- ✅ Quando non ti serve sapere la posizione (indice)
- ✅ Per rendere il codice più leggibile
- ❌ Non usarlo se devi modificare la lista mentre la scorri (usa for normale)
🏪 Esercizio 1: Gestionale Inventario Semplice
Crea un’applicazione per gestire un inventario di prodotti.
L’utente può aggiungere prodotti con nome, prezzo, quantità e categoria,
visualizzarli in una ListBox e rimuoverli.
- TextBox:
txtNome→ Nome prodotto - TextBox:
txtPrezzo→ Prezzo - TextBox:
txtQuantita→ Quantità - ComboBox:
cmbCategoria→ Categoria prodotto - Button:
btnAggiungi→ Aggiungi prodotto - Button:
btnRimuovi→ Rimuovi prodotto selezionato - ListBox:
lstInventario→ Visualizza elenco prodotti
using System;
using System.Collections.Generic;
using System.Windows.Forms;
namespace InventarioSemplice
{
public partial class Form1 : Form
{
// ═══════════════════════════════════════
// VARIABILE GLOBALE: Lista prodotti
// ═══════════════════════════════════════
private List<string> listaProdotti;
public Form1()
{
InitializeComponent();
// Inizializza la lista vuota
listaProdotti = new List<string>();
// Popola la ComboBox categorie
InizializzaCategorie();
}
// ═══════════════════════════════════════
// METODO: Popola ComboBox categorie
// ═══════════════════════════════════════
private void InizializzaCategorie()
{
cmbCategoria.Items.Add("Scegli categoria");
cmbCategoria.Items.Add("Abbigliamento");
cmbCategoria.Items.Add("Detersivi");
cmbCategoria.Items.Add("Casa");
cmbCategoria.Items.Add("Alimentari");
cmbCategoria.Items.Add("Sport");
cmbCategoria.Items.Add("Elettronica");
// Seleziona la prima opzione di default
cmbCategoria.SelectedIndex = 0;
}
// ═══════════════════════════════════════
// EVENTO: Click su Aggiungi
// ═══════════════════════════════════════
private void btnAggiungi_Click(object sender, EventArgs e)
{
// 1️⃣ VALIDAZIONE: Controlla campi vuoti
if (!ControllaCampi())
return; // Esci se non valido
// 2️⃣ VALIDAZIONE: Controlla che prezzo e quantità siano numeri
if (!ValidaPrezzo(txtPrezzo.Text) || !ValidaQuantita(txtQuantita.Text))
return;
// 3️⃣ CONVERSIONE prezzo con formattazione
double prezzo = Convert.ToDouble(txtPrezzo.Text);
string prezzoFormattato = prezzo.ToString("C"); // Es: € 5,50
// 4️⃣ CREA la stringa prodotto
string prodotto = $"{txtNome.Text} - {txtQuantita.Text} - {prezzoFormattato} - {cmbCategoria.SelectedItem}";
// 5️⃣ AGGIUNGI alla lista
listaProdotti.Add(prodotto);
// 6️⃣ AGGIORNA la ListBox
AggiornaInventario();
// 7️⃣ PULISCI i campi
PulisciCampi();
}
// ═══════════════════════════════════════
// METODO: Controlla campi vuoti
// ═══════════════════════════════════════
private bool ControllaCampi()
{
if (string.IsNullOrEmpty(txtNome.Text))
{
MessageBox.Show("Inserisci il nome del prodotto!",
"Attenzione",
MessageBoxButtons.OK,
MessageBoxIcon.Warning);
return false;
}
if (string.IsNullOrEmpty(txtPrezzo.Text))
{
MessageBox.Show("Inserisci il prezzo!",
"Attenzione",
MessageBoxButtons.OK,
MessageBoxIcon.Warning);
return false;
}
if (string.IsNullOrEmpty(txtQuantita.Text))
{
MessageBox.Show("Inserisci la quantità!",
"Attenzione",
MessageBoxButtons.OK,
MessageBoxIcon.Warning);
return false;
}
if (cmbCategoria.SelectedIndex == 0)
{
MessageBox.Show("Seleziona una categoria!",
"Attenzione",
MessageBoxButtons.OK,
MessageBoxIcon.Warning);
return false;
}
return true; // Tutto OK!
}
// ═══════════════════════════════════════
// METODO: Valida prezzo (deve essere numero)
// ═══════════════════════════════════════
private bool ValidaPrezzo(string testo)
{
try
{
Convert.ToDouble(testo);
return true;
}
catch
{
MessageBox.Show("Il prezzo deve essere un numero valido!",
"Errore",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
return false;
}
}
// ═══════════════════════════════════════
// METODO: Valida quantità (deve essere intero)
// ═══════════════════════════════════════
private bool ValidaQuantita(string testo)
{
try
{
Convert.ToInt32(testo);
return true;
}
catch
{
MessageBox.Show("La quantità deve essere un numero intero!",
"Errore",
MessageBoxButtons.OK,
MessageBoxIcon.Error);
return false;
}
}
// ═══════════════════════════════════════
// METODO: Aggiorna ListBox con i prodotti
// ═══════════════════════════════════════
private void AggiornaInventario()
{
// 1. Pulisci la ListBox
lstInventario.Items.Clear();
// 2. Riempi con tutti i prodotti dalla List
foreach (string prodotto in listaProdotti)
{
lstInventario.Items.Add(prodotto);
}
}
// ═══════════════════════════════════════
// METODO: Pulisce i campi input
// ═══════════════════════════════════════
private void PulisciCampi()
{
txtNome.Text = "";
txtPrezzo.Text = "";
txtQuantita.Text = "";
cmbCategoria.SelectedIndex = 0;
// Metti il focus sul primo campo
txtNome.Focus();
}
// ═══════════════════════════════════════
// EVENTO: Click su Rimuovi
// ═══════════════════════════════════════
private void btnRimuovi_Click(object sender, EventArgs e)
{
// 1️⃣ Controlla che ci sia una selezione
if (lstInventario.SelectedIndex == -1)
{
MessageBox.Show("Seleziona un prodotto da eliminare!",
"Attenzione",
MessageBoxButtons.OK,
MessageBoxIcon.Warning);
return;
}
// 2️⃣ Rimuovi dalla List (alla posizione selezionata)
listaProdotti.RemoveAt(lstInventario.SelectedIndex);
// 3️⃣ Aggiorna la ListBox
AggiornaInventario();
}
}
}
Scenario: Aggiungere un Prodotto
1️⃣ L’utente compila:
- Nome: “Maglietta Nike”
- Prezzo: “29.99”
- Quantità: “5”
- Categoria: “Abbigliamento”
2️⃣ Clicca “Aggiungi”:
- ControllaCampi() → ✅ Tutti compilati
- ValidaPrezzo() → ✅ “29.99” è un numero
- ValidaQuantita() → ✅ “5” è un intero
3️⃣ Crea la stringa:
"Maglietta Nike - 5 - € 29,99 - Abbigliamento"
4️⃣ Aggiunge alla List:
listaProdotti.Add(prodotto);
5️⃣ Aggiorna la ListBox:
Pulisce lstInventario.Items e la riempie con tutti i prodotti dalla List usando foreach
✅ Risultato Visibile:
□ Maglietta Nike – 5 – € 29,99 – Abbigliamento
🏨 Esercizio 2: Prenotazione Hotel
Crea un sistema di prenotazione hotel dove l’utente sceglie il tipo di camera
(Singola/Doppia/Suite) e può aggiungere servizi extra da una lista.
L’app calcola il prezzo totale!
- ComboBox:
cmbCamera→ Tipi camera (Singola €80, Doppia €120, Suite €200) - ListBox:
lstServiziDisponibili→ Servizi disponibili - ListBox:
lstServiziScelti→ Servizi scelti dall’utente - Button:
btnAggiungiServizio→ Sposta servizio da disponibili a scelti - Button:
btnRimuoviServizio→ Toglie servizio dai scelti - Button:
btnCalcolaTotale→ Calcola il prezzo finale - Label:
lblTotale→ Mostra il totale
using System;
using System.Windows.Forms;
namespace PrenotazioneHotel
{
public partial class Form1 : Form
{
// Prezzi camere
private int prezzoSingola = 80;
private int prezzoDoppia = 120;
private int prezzoSuite = 200;
// Prezzi servizi
private int prezzoColazione = 15;
private int prezzoParcheggio = 10;
private int prezzoSpa = 25;
public Form1()
{
InitializeComponent();
InizializzaCamere();
InizializzaServizi();
}
// ═══════════════════════════════════════
// Popola ComboBox camere
// ═══════════════════════════════════════
private void InizializzaCamere()
{
cmbCamera.Items.Add("Camera Singola - € 80");
cmbCamera.Items.Add("Camera Doppia - € 120");
cmbCamera.Items.Add("Suite - € 200");
cmbCamera.SelectedIndex = 0; // Seleziona la prima
}
// ═══════════════════════════════════════
// Popola ListBox servizi disponibili
// ═══════════════════════════════════════
private void InizializzaServizi()
{
lstServiziDisponibili.Items.Add("Colazione in camera - € 15");
lstServiziDisponibili.Items.Add("Parcheggio - € 10");
lstServiziDisponibili.Items.Add("Accesso SPA - € 25");
}
// ═══════════════════════════════════════
// EVENTO: Aggiungi servizio
// ═══════════════════════════════════════
private void btnAggiungiServizio_Click(object sender, EventArgs e)
{
// Controlla che ci sia una selezione
if (lstServiziDisponibili.SelectedIndex == -1)
{
MessageBox.Show("Seleziona un servizio da aggiungere!");
return;
}
// Prendi il servizio selezionato
string servizio = lstServiziDisponibili.SelectedItem.ToString();
// Aggiungilo ai servizi scelti
lstServiziScelti.Items.Add(servizio);
// Rimuovilo dai disponibili
lstServiziDisponibili.Items.RemoveAt(lstServiziDisponibili.SelectedIndex);
}
// ═══════════════════════════════════════
// EVENTO: Rimuovi servizio
// ═══════════════════════════════════════
private void btnRimuoviServizio_Click(object sender, EventArgs e)
{
// Controlla selezione
if (lstServiziScelti.SelectedIndex == -1)
{
MessageBox.Show("Seleziona un servizio da rimuovere!");
return;
}
// Prendi il servizio
string servizio = lstServiziScelti.SelectedItem.ToString();
// Rimettilo nei disponibili
lstServiziDisponibili.Items.Add(servizio);
// Toglilo dai scelti
lstServiziScelti.Items.RemoveAt(lstServiziScelti.SelectedIndex);
}
// ═══════════════════════════════════════
// EVENTO: Calcola totale
// ═══════════════════════════════════════
private void btnCalcolaTotale_Click(object sender, EventArgs e)
{
int totale = 0;
// 1️⃣ Aggiungi prezzo camera
string camera = cmbCamera.SelectedItem.ToString();
if (camera.Contains("Singola"))
totale += prezzoSingola;
else if (camera.Contains("Doppia"))
totale += prezzoDoppia;
else if (camera.Contains("Suite"))
totale += prezzoSuite;
// 2️⃣ Aggiungi prezzi servizi scelti
foreach (string servizio in lstServiziScelti.Items)
{
if (servizio.Contains("Colazione"))
totale += prezzoColazione;
else if (servizio.Contains("Parcheggio"))
totale += prezzoParcheggio;
else if (servizio.Contains("SPA"))
totale += prezzoSpa;
}
// 3️⃣ Mostra il totale
lblTotale.Text = $"Totale: € {totale}";
lblTotale.ForeColor = Color.Green;
}
}
}
✅ Esercizio 3: Gestione Task con Priorità
Crea una To-Do List dove l’utente può aggiungere task con un livello di
priorità (Bassa/Media/Alta). I task vengono mostrati con l’etichetta di priorità!
- TextBox:
txtTask→ Descrizione task - ComboBox:
cmbPriorita→ Priorità (Bassa/Media/Alta) - Button:
btnAggiungi→ Aggiungi task - Button:
btnRimuovi→ Rimuovi task selezionato - ListBox:
lstTask→ Elenco task
using System;
using System.Collections.Generic;
using System.Windows.Forms;
namespace GestioneTask
{
public partial class Form1 : Form
{
private List<string> listaTask;
public Form1()
{
InitializeComponent();
listaTask = new List<string>();
InizializzaPriorita();
}
// ═══════════════════════════════════════
// Popola ComboBox priorità
// ═══════════════════════════════════════
private void InizializzaPriorita()
{
cmbPriorita.Items.Add("Bassa");
cmbPriorita.Items.Add("Media");
cmbPriorita.Items.Add("Alta");
cmbPriorita.SelectedIndex = 1; // Media di default
}
// ═══════════════════════════════════════
// EVENTO: Aggiungi task
// ═══════════════════════════════════════
private void btnAggiungi_Click(object sender, EventArgs e)
{
// Controlla campo vuoto
if (string.IsNullOrEmpty(txtTask.Text))
{
MessageBox.Show("Scrivi un task!");
return;
}
// Crea la stringa task con priorità
string priorita = cmbPriorita.SelectedItem.ToString();
string task = $"[{priorita}] {txtTask.Text}";
// Aggiungi alla lista
listaTask.Add(task);
// Aggiorna ListBox
AggiornaListaTask();
// Pulisci il campo
txtTask.Text = "";
txtTask.Focus();
}
// ═══════════════════════════════════════
// Aggiorna ListBox
// ═══════════════════════════════════════
private void AggiornaListaTask()
{
lstTask.Items.Clear();
foreach (string task in listaTask)
{
lstTask.Items.Add(task);
}
}
// ═══════════════════════════════════════
// EVENTO: Rimuovi task
// ═══════════════════════════════════════
private void btnRimuovi_Click(object sender, EventArgs e)
{
if (lstTask.SelectedIndex == -1)
{
MessageBox.Show("Seleziona un task da rimuovere!");
return;
}
listaTask.RemoveAt(lstTask.SelectedIndex);
AggiornaListaTask();
}
}
}
🎓 Riepilogo: Cosa Hai Imparato
Differenze, quando usare l’uno o l’altro, proprietà Items, SelectedItem, SelectedIndex
Lista dinamica che può crescere, Add(), Remove(), RemoveAt(), Contains(), Count
Scorrere automaticamente tutti gli elementi di una lista per processarli
Memorizzare dati in List, sincronizzare con ListBox usando metodo AggiornaListBox()
Controllo campi vuoti, validazione numeri, gestione SelectedIndex == -1
Inventario, Prenotazione Hotel, Gestione Task – applicazioni reali e funzionanti
🚀 Prossimi Passi
📖 Nella Lezione 5 Imparerai:
- 🚗 Classi Personalizzate: Creare la classe Automobile invece di usare stringhe
- 📊 List<Automobile>: Liste di oggetti complessi
- 🔧 Progetti Avanzati: Parco Auto con modifica, ordinamento, statistiche
- 💾 Persistenza Dati: Salvare e caricare da file CSV/TXT
🎯 Passerai dalle stringhe semplici agli oggetti complessi!
Lezione 4 – ListBox e ComboBox: Teoria e Pratica
Corso C# Completo con Interfaccia Grafica – Da Zero a Esperto
