Programmazione ad Eventi con Windows Forms

Esercizi pratici con TextBox, Label, Button e gestione eventi

Concetti fondamentali:

TextBox: controllo per l’inserimento di testo
Label: controllo per visualizzare testo
Button: controllo che genera un evento Click
Event Handler: metodo che viene eseguito quando si verifica un evento

Introduzione alla Programmazione ad Eventi

Nella programmazione Windows Forms, gli eventi sono azioni che accadono durante l’esecuzione di un programma, come il click di un pulsante, la digitazione in una TextBox, ecc. La programmazione ad eventi permette di eseguire codice in risposta a questi eventi.

Esercizio 1: Somma di Due Numeri con Interfaccia Grafica

▶ Obiettivo

Creare un’interfaccia con due TextBox per inserire i numeri, un Button per calcolare e una Label per visualizzare il risultato.

1

Progettazione dell’interfaccia:

  • Due TextBox (txtNumero1, txtNumero2)
  • Un Button (btnCalcola) con testo “Calcola Somma”
  • Una Label (lblRisultato) per visualizzare il risultato

2

Gestione dell’evento Click:

C#
private void btnCalcola_Click(object sender, EventArgs e)
{
    // Controllo che i campi non siano vuoti
    if (string.IsNullOrEmpty(txtNumero1.Text) || string.IsNullOrEmpty(txtNumero2.Text))
    {
        lblRisultato.Text = "Inserisci entrambi i numeri!";
        return;
    }

    try
    {
        // Conversione dei valori usando Convert
        double numero1 = Convert.ToDouble(txtNumero1.Text);
        double numero2 = Convert.ToDouble(txtNumero2.Text);

        double somma = numero1 + numero2;

        // Visualizzazione del risultato usando ToString
        lblRisultato.Text = "La somma è: " + somma.ToString();
    }
    catch (FormatException)
    {
        lblRisultato.Text = "Inserisci valori numerici validi!";
    }
    catch (Exception ex)
    {
        lblRisultato.Text = "Errore: " + ex.Message;
    }
}

3

Eventi TextChanged per validazione:

C#
private void txtNumero1_TextChanged(object sender, EventArgs e)
{
    // Abilita il pulsante solo se entrambi i campi contengono numeri validi
    btnCalcola.Enabled = AreInputsValid();
}

private void txtNumero2_TextChanged(object sender, EventArgs e)
{
    btnCalcola.Enabled = AreInputsValid();
}

private bool AreInputsValid()
{
    try
    {
        if (!string.IsNullOrEmpty(txtNumero1.Text))
            Convert.ToDouble(txtNumero1.Text);

        if (!string.IsNullOrEmpty(txtNumero2.Text))
            Convert.ToDouble(txtNumero2.Text);

        return true;
    }
    catch
    {
        return false;
    }
}

Metodi Utilizzati – Esercizio 1

string.IsNullOrEmpty(string)

Metodo statico che verifica se una stringa è null o vuota (“”). Restituisce true se la stringa è null o stringa vuota, altrimenti false.

bool result = string.IsNullOrEmpty(textBox.Text);
Nota: Questo metodo è preferibile rispetto al controllo manuale (text == null || text == “”) perché più efficiente e leggibile.
Convert.ToDouble(string)

Metodo della classe Convert che converte una rappresentazione stringa di un numero in un valore double.

double number = Convert.ToDouble(“123.45”);
Nota: Se la stringa non è in un formato numerico valido, questo metodo genera un’eccezione FormatException.
ToString()

Metodo che converte un valore nel suo equivalente rappresentazione stringa. Tutti i tipi in C# ereditano questo metodo dalla classe Object.

string text = number.ToString();
Nota: Per i numeri, è possibile specificare formati personalizzati (es. number.ToString(“F2”) per due decimali).
Control.Text (proprietà)

Proprietà che rappresenta il testo associato a un controllo (TextBox, Label, Button, ecc.).

// Ottenere il testo
string input = textBox.Text;
// Impostare il testo
label.Text = “Risultato: ” + result;
Control.Enabled (proprietà)

Proprietà che indica se il controllo è abilitato (true) o disabilitato (false). Un controllo disabilitato appare in grigio e non risponde agli eventi utente.

button.Enabled = true; // Abilita il pulsante
button.Enabled = false; // Disabilita il pulsante
Gestione eccezioni (try-catch)

Costrutto per gestire eccezioni (errori a runtime). Il codice nel blocco try viene eseguito, e se si verifica un’eccezione, il controllo passa al blocco catch appropriato.

try
{
// Codice che potrebbe generare un’eccezione
}
catch (FormatException ex)
{
// Gestione specifica per FormatException
lblRisultato.Text = “Inserisci valori numerici validi!”;
}
catch (Exception ex)
{
// Gestione per tutte le altre eccezioni
lblRisultato.Text = “Errore: ” + ex.Message;
}
Nota: È buona pratica gestire eccezioni specifiche prima di quelle generiche.

Esercizio 2: Verifica Numero Pari o Dispari

▶ Obiettivo

Creare un’interfaccia per verificare se un numero è pari o dispari usando l’operatore modulo (%).


Verifica numero pari o dispari

1

Progettazione dell’interfaccia:

  • Una TextBox (txtNumero)
  • Un Button (btnVerifica) con testo “Verifica”
  • Una Label (lblRisultato) per visualizzare il risultato

2

Gestione dell’evento Click:

C#
private void btnVerifica_Click(object sender, EventArgs e)
{
    if (string.IsNullOrEmpty(txtNumero.Text))
    {
        lblRisultato.Text = "Inserisci un numero!";
        return;
    }

    try
    {
        // Conversione usando Convert.ToInt32
        int numero = Convert.ToInt32(txtNumero.Text);

        // Utilizzo dell'operatore modulo per verificare se è pari
        if (numero % 2 == 0)
        {
            lblRisultato.Text = numero.ToString() + " è un numero PARI";
            lblRisultato.ForeColor = Color.Blue;
        }
        else
        {
            lblRisultato.Text = numero.ToString() + " è un numero DISPARI";
            lblRisultato.ForeColor = Color.Red;
        }
    }
    catch (FormatException)
    {
        lblRisultato.Text = "Inserisci un numero intero valido!";
        lblRisultato.ForeColor = Color.Black;
    }
    catch (Exception ex)
    {
        lblRisultato.Text = "Errore: " + ex.Message;
        lblRisultato.ForeColor = Color.Black;
    }
}

3

Evento KeyPress per validazione input:

C#
private void txtNumero_KeyPress(object sender, KeyPressEventArgs e)
{
    // Permette solo numeri, backspace e segno meno (per numeri negativi)
    if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar) && e.KeyChar != '-')
    {
        e.Handled = true;
    }

    // Permette il segno meno solo all'inizio
    if (e.KeyChar == '-' && (sender as TextBox).Text.IndexOf('-') > -1)
    {
        e.Handled = true;
    }
}

Nuovi Metodi Utilizzati – Esercizio 2

Convert.ToInt32(string)

Metodo della classe Convert che converte una rappresentazione stringa di un numero in un valore intero a 32 bit (int).

int number = Convert.ToInt32(“123”);
Nota: Se la stringa non è in un formato numerico valido, questo metodo genera un’eccezione FormatException.
Operatore % (modulo)

Operatore che restituisce il resto della divisione tra due numeri. Utilizzato per verificare se un numero è pari (numero % 2 == 0) o dispari (numero % 2 != 0).

int remainder = 10 % 3; // Restituisce 1
bool isEven = (number % 2 == 0); // True se il numero è pari
Control.ForeColor (proprietà)

Proprietà che rappresenta il colore del testo di un controllo. Accetta valori della struttura Color.

label.ForeColor = Color.Red;
label.ForeColor = Color.FromArgb(255, 0, 0); // Rosso usando valori RGB
char.IsControl(char)

Metodo statico che indica se un carattere è un carattere di controllo (come tab, backspace, ecc.).

bool isControlChar = char.IsControl(‘\t’); // Restituisce true
char.IsDigit(char)

Metodo statico che indica se un carattere è una cifra decimale (0-9).

bool isDigit = char.IsDigit(‘5’); // Restituisce true
TextBox.IndexOf(char)

Metodo della classe string che restituisce l’indice della prima occorrenza del carattere specificato nella stringa, o -1 se il carattere non viene trovato.

int index = textBox.Text.IndexOf(‘-‘);

Esercizio 3: Valutazione del Voto con Interfaccia

▶ Obiettivo

Creare un’interfaccia per convertire un voto numerico in una valutazione letterale.

1

Progettazione dell’interfaccia:

  • Una TextBox (txtVoto) per inserire il voto
  • Un Button (btnValuta) con testo “Valuta”
  • Una Label (lblValutazione) per visualizzare il risultato

2

Gestione dell’evento Click con switch:

C#
private void btnValuta_Click(object sender, EventArgs e)
{
    if (string.IsNullOrEmpty(txtVoto.Text))
    {
        lblValutazione.Text = "Inserisci un voto!";
        return;
    }

    try
    {
        // Conversione usando Convert.ToInt32
        int voto = Convert.ToInt32(txtVoto.Text);
        string valutazione;

        switch (voto)
        {
            case >= 90 and <= 100: valutazione = "ECCELLENTE"; lblValutazione.ForeColor = Color.Green; break; case >= 80 and < 90: valutazione = "MOLTO BUONO"; lblValutazione.ForeColor = Color.DarkGreen; break; case >= 70 and < 80: valutazione = "BUONO"; lblValutazione.ForeColor = Color.Blue; break; case >= 60 and < 70: valutazione = "SUFFICIENTE"; lblValutazione.ForeColor = Color.Orange; break; case >= 0 and < 60:
                valutazione = "INSUFFICIENTE";
                lblValutazione.ForeColor = Color.Red;
                break;

            default:
                valutazione = "Voto non valido! Inserisci un valore tra 0 e 100";
                lblValutazione.ForeColor = Color.Black;
                break;
        }

        lblValutazione.Text = "Valutazione: " + valutazione;
    }
    catch (FormatException)
    {
        lblValutazione.Text = "Inserisci un voto numerico valido!";
        lblValutazione.ForeColor = Color.Black;
    }
    catch (Exception ex)
    {
        lblValutazione.Text = "Errore: " + ex.Message;
        lblValutazione.ForeColor = Color.Black;
    }
}

Esercizio 4: Calcolatrice Semplice con Interfaccia

▶ Obiettivo

Creare un’interfaccia per una calcolatrice che esegua operazioni matematiche di base.

1

Progettazione dell’interfaccia:

  • Due TextBox (txtNumero1, txtNumero2)
  • Quattro Button per le operazioni (btnSomma, btnSottrai, btnMoltiplica, btnDividi)
  • Una Label (lblRisultato) per visualizzare il risultato
  • Una Label (lblOperazione) per visualizzare l’operazione corrente

2

Gestione degli eventi Click per ogni operazione:

C#
private void btnSomma_Click(object sender, EventArgs e)
{
    CalcolaOperazione('+');
}

private void btnSottrai_Click(object sender, EventArgs e)
{
    CalcolaOperazione('-');
}

private void btnMoltiplica_Click(object sender, EventArgs e)
{
    CalcolaOperazione('*');
}

private void btnDividi_Click(object sender, EventArgs e)
{
    CalcolaOperazione('/');
}

private void CalcolaOperazione(char operatore)
{
    if (string.IsNullOrEmpty(txtNumero1.Text) || string.IsNullOrEmpty(txtNumero2.Text))
    {
        lblRisultato.Text = "Inserisci entrambi i numeri!";
        return;
    }

    try
    {
        // Conversione usando Convert.ToDouble
        double num1 = Convert.ToDouble(txtNumero1.Text);
        double num2 = Convert.ToDouble(txtNumero2.Text);

        double risultato = 0;
        bool operazioneValida = true;

        switch (operatore)
        {
            case '+':
                risultato = num1 + num2;
                lblOperazione.Text = "Operazione: Somma";
                break;
            case '-':
                risultato = num1 - num2;
                lblOperazione.Text = "Operazione: Sottrazione";
                break;
            case '*':
                risultato = num1 * num2;
                lblOperazione.Text = "Operazione: Moltiplicazione";
                break;
            case '/':
                if (num2 != 0)
                {
                    risultato = num1 / num2;
                    lblOperazione.Text = "Operazione: Divisione";
                }
                else
                {
                    lblRisultato.Text = "Errore: divisione per zero!";
                    operazioneValida = false;
                }
                break;
        }

        if (operazioneValida)
        {
            // Visualizzazione del risultato usando ToString
            lblRisultato.Text = "Risultato: " + risultato.ToString();
        }
    }
    catch (FormatException)
    {
        lblRisultato.Text = "Inserisci valori numerici validi!";
    }
    catch (Exception ex)
    {
        lblRisultato.Text = "Errore: " + ex.Message;
    }
}

3

Evento Form Load per inizializzazione:

C#
private void Form1_Load(object sender, EventArgs e)
{
    // Inizializza i controlli all'avvio del form
    lblOperazione.Text = "Seleziona un'operazione";
    lblRisultato.Text = "Risultato: ";

    // Disabilita i pulsanti finché non ci sono valori validi
    AbilitaPulsanti(false);
}

private void txtNumero1_TextChanged(object sender, EventArgs e)
{
    // Abilita i pulsanti solo se entrambi i campi contengono numeri validi
    AbilitaPulsanti(AreInputsValid());
}

private void txtNumero2_TextChanged(object sender, EventArgs e)
{
    AbilitaPulsanti(AreInputsValid());
}

private bool AreInputsValid()
{
    try
    {
        if (!string.IsNullOrEmpty(txtNumero1.Text))
            Convert.ToDouble(txtNumero1.Text);

        if (!string.IsNullOrEmpty(txtNumero2.Text))
            Convert.ToDouble(txtNumero2.Text);

        return true;
    }
    catch
    {
        return false;
    }
}

private void AbilitaPulsanti(bool abilita)
{
    btnSomma.Enabled = abilita;
    btnSottrai.Enabled = abilita;
    btnMoltiplica.Enabled = abilita;
    btnDividi.Enabled = abilita;
}

Esercizio 5: Convertitore Temperatura

▶ Obiettivo

Creare un’interfaccia per convertire la temperatura tra Celsius e Fahrenheit.

1

Progettazione dell’interfaccia:

  • Una TextBox (txtTemperatura) per inserire il valore
  • Due RadioButton (rbCelsius, rbFahrenheit) per selezionare il tipo di conversione
  • Un Button (btnConverti) con testo “Converti”
  • Una Label (lblRisultato) per visualizzare il risultato

2

Gestione dell’evento Click:

C#
private void btnConverti_Click(object sender, EventArgs e)
{
    if (string.IsNullOrEmpty(txtTemperatura.Text))
    {
        lblRisultato.Text = "Inserisci una temperatura!";
        return;
    }

    try
    {
        // Conversione usando Convert.ToDouble
        double temperatura = Convert.ToDouble(txtTemperatura.Text);
        double risultato;
        string fromUnit, toUnit;

        if (rbCelsius.Checked)
        {
            // Conversione da Celsius a Fahrenheit: F = C * 9/5 + 32
            risultato = temperatura * 9 / 5 + 32;
            fromUnit = "Celsius";
            toUnit = "Fahrenheit";
        }
        else
        {
            // Conversione da Fahrenheit a Celsius: C = (F - 32) * 5/9
            risultato = (temperatura - 32) * 5 / 9;
            fromUnit = "Fahrenheit";
            toUnit = "Celsius";
        }

        // Visualizzazione del risultato usando ToString con formattazione
        lblRisultato.Text = temperatura.ToString() + "° " + fromUnit + " = " +
        risultato.ToString("0.##") + "° " + toUnit;
    }
    catch (FormatException)
    {
        lblRisultato.Text = "Inserisci un valore numerico valido!";
    }
    catch (Exception ex)
    {
        lblRisultato.Text = "Errore: " + ex.Message;
    }
}

3

Evento CheckedChanged per i RadioButton:

C#
private void rbCelsius_CheckedChanged(object sender, EventArgs e)
{
    // Aggiorna l'interfaccia quando cambia la selezione
    AggiornaInterfaccia();
}

private void rbFahrenheit_CheckedChanged(object sender, EventArgs e)
{
    AggiornaInterfaccia();
}

private void AggiornaInterfaccia()
{
    if (rbCelsius.Checked)
    {
        lblTitolo.Text = "Converti da Celsius a Fahrenheit";
    }
    else
    {
        lblTitolo.Text = "Converti da Fahrenheit a Celsius";
    }

    // Pulisce il risultato quando cambia il tipo di conversione
    lblRisultato.Text = "";
}

Consigli per la Programmazione ad Eventi

Migliori Pratiche

  • Nomi significativi: Assegna nomi descrittivi ai controlli (es. btnCalcola invece di button1)
  • Validazione input: Verifica sempre che i dati inseriti siano validi prima di elaborarli
  • Gestione errori: Utilizza blocchi try-catch per gestire eventuali eccezioni
  • Feedback utente: Fornisci sempre feedback visivo (es. cambiamento colore, messaggi di errore)
  • Separazione logica: Separa la logica di business dalla gestione degli eventi quando possibile

Eventi Comuni dei Controlli

Controllo Evento Quando si verifica
Button Click Quando si clicca sul pulsante
TextBox TextChanged Quando il testo viene modificato
TextBox KeyPress Quando viene premuto un tasto mentre la TextBox ha focus
RadioButton CheckedChanged Quando cambia lo stato di selezione
Form Load Quando il form viene caricato
Torna in alto