Vai al contenuto

Timer e ProgressBar

Crea applicazioni dinamiche che si aggiornano nel tempo!.

Cosa Imparerai in Questa Lezione

Fino ad ora le tue app facevano qualcosa solo quando l'utente cliccava un pulsante. Oggi scoprirai come creare applicazioni che si muovono da sole: orologi che tic-taccano, cronometri che contano, barre di caricamento che si riempiono! โฐ๐Ÿš€

โœจ I Nuovi Controlli Dinamici

โฑ๏ธ Timer

Esegue codice automaticamente ogni tot millisecondi! Perfetto per orologi, countdown, animazioni, controlli periodici.

Es: Ogni 1000ms (1 secondo) aggiorna l'ora corrente

๐Ÿ“Š ProgressBar

Barra di progresso che si riempie! Mostra all'utente quanto manca al completamento di un'operazione.

Es: Download file 0% โ–ฑโ–ฑโ–ฑโ–ฑโ–ฑ โ†’ 100% โ–ฐโ–ฐโ–ฐโ–ฐโ–ฐ

๐Ÿ”” NotifyIcon

Icona nella system tray (in basso a destra vicino all'orologio). Per app che girano in background e notifiche.

Es: Promemoria che compare ogni 30 minuti

๐Ÿ“š Prerequisiti

Prima di iniziare, dovresti aver completato:

  • โœ… TabControl e DataGridView
  • โœ… Gestione eventi
  • โœ… Variabili e operazioni matematiche base

Cos'รจ il Timer?

Analogia della Vita Reale

Hai presente la sveglia che suona ogni mattina alla stessa ora? O il metronomo dei musicisti che fa "tic-tac" a ritmo costante? Il Timer รจ esattamente questo: un componente che "suona" (esegue codice) ogni tot tempo!

๐Ÿ’ก Come Funziona il Timer

1๏ธโƒฃ Imposti l'intervallo (es: 1000 millisecondi = 1 secondo)

2๏ธโƒฃ Scrivi cosa deve fare nel metodo Timer_Tick

3๏ธโƒฃ Avvii il Timer con timer.Start()

4๏ธโƒฃ Il codice si ripete automaticamente ogni intervallo!

โš™๏ธ Proprietร  Principali:

  • Interval: Tempo in millisecondi (1000 = 1 secondo)
  • Enabled: true = attivo, false = fermo

๐ŸŽฎ Metodi Principali:

  • Start(): Avvia il timer
  • Stop(): Ferma il timer

โš ๏ธ IMPORTANTE: Millisecondi!

Il Timer conta in millisecondi (ms), non secondi! โ€ข 1000 ms = 1 secondo โ€ข 500 ms = 0.5 secondi (mezzo secondo) โ€ข 60000 ms = 60 secondi = 1 minuto โ€ข 100 ms = 0.1 secondi (velocissimo!)

Esercizio 1: Orologio Digitale

Obiettivo

Crea un orologio digitale che mostra l'ora corrente e si aggiorna automaticamente ogni secondo! Come quello del computer ma nel TUO programma! ๐Ÿ•

  1. Crea l'Interfaccia

๐ŸŽจ Controlli Necessari:

  • Label: lbl_ora
    • Text = "00:00:00"
    • Font = Molto grande (es: Arial, 48pt, Bold)
    • ForeColor = Colore che ti piace
    • TextAlign = MiddleCenter
  • Label: lbl_data
    • Text = "01/01/2025"
    • Font = Medio (es: Arial, 16pt)
    • TextAlign = MiddleCenter
  • Timer: timer_orologio
    • Interval = 1000 (1 secondo)
    • Enabled = true (si avvia automaticamente)

๐Ÿ’ก Come Aggiungere il Timer:

  1. Nella Toolbox cerca "Timer"

  2. Trascinalo sul form

  3. Appare in basso (non รจ visibile all'utente!)

  4. Imposta Properties โ†’ Interval = 1000

  5. Properties โ†’ Enabled = true

  6. Il Codice

OrologioDigitale.cs

using System;
using System.Windows.Forms;

namespace OrologioDigitale
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();

            // Imposta ora e data all'avvio
            AggiornaOrario();
        }

        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        // EVENTO TIMER: Si esegue ogni 1 secondo!
        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        private void timer_orologio_Tick(object sender, EventArgs e)
        {
            // Aggiorna l'orario
            AggiornaOrario();
        }

        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        // METODO: Aggiorna ora e data
        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        private void AggiornaOrario()
        {
            // Ottieni l'ora corrente
            DateTime adesso = DateTime.Now;

            // Formatta l'ora come HH:mm:ss (24 ore)
            lbl_ora.Text = adesso.ToString("HH:mm:ss");

            // Formatta la data come dd/MM/yyyy
            lbl_data.Text = adesso.ToString("dddd, dd MMMM yyyy");

            // BONUS: Cambia colore in base all'ora
            int ora = adesso.Hour;

            if (ora >= 6 && ora < 12)
            {
                // Mattino: Arancione
                lbl_ora.ForeColor = Color.Orange;
            }
            else if (ora >= 12 && ora < 18)
            {
                // Pomeriggio: Blu
                lbl_ora.ForeColor = Color.Blue;
            }
            else
            {
                // Sera/Notte: Viola
                lbl_ora.ForeColor = Color.Purple;
            }
        }
    }
}

๐ŸŽฌ Cosa Succede:

  1. L'app si apre e mostra subito l'ora corrente

  2. Ogni 1 secondo il timer_orologio_Tick viene chiamato automaticamente

  3. Il metodo AggiornaOrario() prende l'ora attuale e la mostra

  4. Il colore cambia in base all'orario (mattino/pomeriggio/sera)

  5. ๐Ÿ”— Collega l'Evento Tick

๐Ÿ“ Procedura:

  1. Seleziona il Timer nella parte bassa del Designer
  2. Premi F4 per aprire Properties
  3. Clicca sull'icona del fulmine โšก (Eventi)
  4. Trova l'evento Tick
  5. Fai doppio click โ†’ Visual Studio crea il metodo

Concetti Chiave - DateTime

DateTime.Now

Ottiene la data e ora corrente del sistema

DateTime adesso = DateTime.Now;

Console.WriteLine(adesso.Hour);        // 14 (ore)
Console.WriteLine(adesso.Minute);      // 30 (minuti)
Console.WriteLine(adesso.Second);      // 45 (secondi)
Console.WriteLine(adesso.Day);         // 15 (giorno)
Console.WriteLine(adesso.Month);       // 1 (gennaio)
Console.WriteLine(adesso.Year);        // 2025

DateTime.ToString(formato)

Formatta data/ora in vari modi

DateTime dt = DateTime.Now;

dt.ToString("HH:mm:ss")           // "14:30:45" (24 ore)
dt.ToString("hh:mm:ss tt")        // "02:30:45 PM" (12 ore)
dt.ToString("dd/MM/yyyy")         // "15/01/2025"
dt.ToString("dddd, dd MMMM yyyy") // "mercoledรฌ, 15 gennaio 2025"
dt.ToString("yyyy-MM-dd")         // "2025-01-15" (formato ISO)

Timer.Start() e .Stop()

Avvia e ferma il timer

timer.Start();    // Inizia a contare
timer.Stop();     // Si ferma
timer.Enabled = true;  // Equivalente a Start()
timer.Enabled = false; // Equivalente a Stop()

Esercizio 2: Cronometro

Obiettivo

Crea un cronometro con pulsanti Start, Stop e Reset! Conta i secondi che passano e puoi fermarlo quando vuoi! โฑ๏ธ

  1. Interfaccia
  • Label: lbl_cronometro (Text = "00:00:00", Font grande)
  • Button: btn_start (Text = "โ–ถ Start")
  • Button: btn_stop (Text = "โธ Stop", Enabled = false)
  • Button: btn_reset (Text = "๐Ÿ”„ Reset")
  • Timer: timer_cronometro (Interval = 100, Enabled = false)
  1. Codice Completo

Cronometro.cs

using System;
using System.Windows.Forms;

namespace Cronometro
{
    public partial class Form1 : Form
    {
        // Variabile per tenere traccia dei millisecondi
        private int millisecondi = 0;

        public Form1()
        {
            InitializeComponent();
        }

        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        // PULSANTE: START
        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        private void btn_start_Click(object sender, EventArgs e)
        {
            // Avvia il timer
            timer_cronometro.Start();

            // Disabilita Start, abilita Stop
            btn_start.Enabled = false;
            btn_stop.Enabled = true;
        }

        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        // PULSANTE: STOP
        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        private void btn_stop_Click(object sender, EventArgs e)
        {
            // Ferma il timer
            timer_cronometro.Stop();

            // Abilita Start, disabilita Stop
            btn_start.Enabled = true;
            btn_stop.Enabled = false;
        }

        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        // PULSANTE: RESET
        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        private void btn_reset_Click(object sender, EventArgs e)
        {
            // Ferma il timer
            timer_cronometro.Stop();

            // Resetta a zero
            millisecondi = 0;

            // Aggiorna display
            AggiornaDisplay();

            // Abilita Start, disabilita Stop
            btn_start.Enabled = true;
            btn_stop.Enabled = false;
        }

        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        // TIMER TICK: Ogni 100ms (0.1 secondi)
        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        private void timer_cronometro_Tick(object sender, EventArgs e)
        {
            // Incrementa di 100 millisecondi
            millisecondi += 100;

            // Aggiorna il display
            AggiornaDisplay();
        }

        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        // AGGIORNA IL DISPLAY
        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        private void AggiornaDisplay()
        {
            // Converti millisecondi in ore:minuti:secondi

            int totaleSecondi = millisecondi / 1000;

            int ore = totaleSecondi / 3600;
            int minuti = (totaleSecondi % 3600) / 60;
            int secondi = totaleSecondi % 60;
            int decimi = (millisecondi % 1000) / 100;

            // Formatta come HH:MM:SS.d
            lbl_cronometro.Text = string.Format("{0:00}:{1:00}:{2:00}.{3}",
                                               ore, minuti, secondi, decimi);
        }
    }
}
  1. ๐ŸŽฌ Come Funziona

๐Ÿ“‹ Flusso:

  1. All'avvio: cronometro fermo a 00:00:00.0
  2. Clicchi Start โ†’ timer si avvia
  3. Ogni 0.1 secondi (100ms) โ†’ millisecondi += 100
  4. Il display si aggiorna: 00:00:00.1, 00:00:00.2, ... 00:00:01.0, ecc.
  5. Clicchi Stop โ†’ si ferma dove รจ arrivato
  6. Clicchi Reset โ†’ torna a 00:00:00.0

Operazioni Matematiche Utili

Operatore % (modulo)

Restituisce il resto della divisione

10 % 3 = 1   // 10 diviso 3 = 3 con resto 1
15 % 4 = 3   // 15 diviso 4 = 3 con resto 3
100 % 60 = 40  // 100 secondi = 1 minuto e 40 secondi

// Uso pratico: convertire secondi in minuti
int totaleSecondi = 150;
int minuti = totaleSecondi / 60;      // 2 minuti
int secondi = totaleSecondi % 60;     // 30 secondi

string.Format()

Formatta stringhe con placeholder e padding

int ore = 5, minuti = 7, secondi = 9;

// Senza Format (brutto)
string tempo = ore + ":" + minuti + ":" + secondi;  // "5:7:9"

// Con Format e padding (bello!)
string tempo = string.Format("{0:00}:{1:00}:{2:00}", ore, minuti, secondi);
// Risultato: "05:07:09"

// {0:00} significa: prendi il primo parametro e mostralo con 2 cifre

ProgressBar: Barra di Progresso

Cos'รจ la ProgressBar?

Hai presente quando installi un programma e vedi la barra che si riempie? "Download in corso... 47% โ–ฐโ–ฐโ–ฐโ–ฐโ–ฑโ–ฑโ–ฑโ–ฑโ–ฑโ–ฑ" Quella รจ una ProgressBar! Mostra visivamente quanto manca al completamento.

โš™๏ธ Proprietร  Principali

  • Minimum: Valore minimo (di solito 0)
  • Maximum: Valore massimo (es: 100 per percentuale)
  • Value: Valore attuale (da Minimum a Maximum)
  • Style: Blocks (a blocchi) o Continuous (continua)

๐Ÿ“Š Esempio Pratico:

Minimum = 0
Maximum = 100
Value = 47

Barra al 47%: โ–ฐโ–ฐโ–ฐโ–ฐโ–ฐโ–ฑโ–ฑโ–ฑโ–ฑโ–ฑ

Esercizio 3: Pomodoro Technique Timer

Obiettivo

Crea un timer per la Pomodoro Technique: 25 minuti di lavoro, poi 5 minuti di pausa. Con ProgressBar che mostra quanto manca! ๐Ÿ…

๐Ÿ“– Cos'รจ la Pomodoro Technique?

Tecnica di produttivitร : lavori concentrato per 25 minuti, poi ti premi con 5 minuti di pausa. Si ripete! Super efficace per studiare!

  1. Interfaccia
  • Label: lbl_stato (Text = "LAVORO", Font grande, Bold)
  • Label: lbl_tempo (Text = "25:00", Font molto grande)
  • ProgressBar: progressBar (Minimum = 0, Maximum = 100)
  • Button: btn_start (Text = "โ–ถ Inizia")
  • Button: btn_pausa (Text = "โธ Pausa", Enabled = false)
  • Button: btn_reset (Text = "๐Ÿ”„ Reset")
  • Timer: timer (Interval = 1000, Enabled = false)
  1. Codice Completo

PomodoroTimer.cs

using System;
using System.Drawing;
using System.Windows.Forms;

namespace PomodoroTimer
{
    public partial class Form1 : Form
    {
        // Costanti (tempo in secondi)
        private const int TEMPO_LAVORO = 25 * 60;    // 25 minuti = 1500 secondi
        private const int TEMPO_PAUSA = 5 * 60;      // 5 minuti = 300 secondi

        // Variabili di stato
        private int secondiRimanenti;
        private int secondiTotali;
        private bool modalitaLavoro = true;  // true = lavoro, false = pausa

        public Form1()
        {
            InitializeComponent();

            // Inizializza con modalitร  lavoro
            ImpostaModalitaLavoro();
        }

        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        // IMPOSTA MODALITร€ LAVORO
        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        private void ImpostaModalitaLavoro()
        {
            modalitaLavoro = true;
            secondiRimanenti = TEMPO_LAVORO;
            secondiTotali = TEMPO_LAVORO;

            lbl_stato.Text = "โฐ TEMPO DI LAVORO";
            lbl_stato.ForeColor = Color.Green;
            this.BackColor = Color.LightGreen;

            AggiornaDisplay();
        }

        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        // IMPOSTA MODALITร€ PAUSA
        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        private void ImpostaModalitaPausa()
        {
            modalitaLavoro = false;
            secondiRimanenti = TEMPO_PAUSA;
            secondiTotali = TEMPO_PAUSA;

            lbl_stato.Text = "โ˜• TEMPO DI PAUSA";
            lbl_stato.ForeColor = Color.Blue;
            this.BackColor = Color.LightBlue;

            AggiornaDisplay();
        }

        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        // PULSANTE: START
        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        private void btn_start_Click(object sender, EventArgs e)
        {
            timer.Start();
            btn_start.Enabled = false;
            btn_pausa.Enabled = true;
        }

        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        // PULSANTE: PAUSA
        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        private void btn_pausa_Click(object sender, EventArgs e)
        {
            timer.Stop();
            btn_start.Enabled = true;
            btn_pausa.Enabled = false;
        }

        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        // PULSANTE: RESET
        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        private void btn_reset_Click(object sender, EventArgs e)
        {
            timer.Stop();
            ImpostaModalitaLavoro();
            btn_start.Enabled = true;
            btn_pausa.Enabled = false;
        }

        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        // TIMER TICK: Ogni secondo
        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        private void timer_Tick(object sender, EventArgs e)
        {
            // Decrementa il tempo
            secondiRimanenti--;

            // Aggiorna il display
            AggiornaDisplay();

            // Controlla se รจ finito
            if (secondiRimanenti <= 0)
            {
                timer.Stop();

                // Suono di notifica
                System.Media.SystemSounds.Beep.Play();

                // Cambia modalitร 
                if (modalitaLavoro)
                {
                    // Finito il lavoro โ†’ inizia pausa
                    MessageBox.Show("โฐ Tempo scaduto!\n\nHai lavorato per 25 minuti.\nAdesso 5 minuti di pausa! โ˜•",
                                  "Pomodoro",
                                  MessageBoxButtons.OK,
                                  MessageBoxIcon.Information);

                    ImpostaModalitaPausa();
                }
                else
                {
                    // Finita la pausa โ†’ inizia lavoro
                    MessageBox.Show("โ˜• Pausa finita!\n\nTorna al lavoro per altri 25 minuti! ๐Ÿ’ช",
                                  "Pomodoro",
                                  MessageBoxButtons.OK,
                                  MessageBoxIcon.Information);

                    ImpostaModalitaLavoro();
                }

                btn_start.Enabled = true;
                btn_pausa.Enabled = false;
            }
        }

        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        // AGGIORNA DISPLAY
        // โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•
        private void AggiornaDisplay()
        {
            // Converti in minuti:secondi
            int minuti = secondiRimanenti / 60;
            int secondi = secondiRimanenti % 60;

            // Mostra il tempo
            lbl_tempo.Text = string.Format("{0:00}:{1:00}", minuti, secondi);

            // Aggiorna la ProgressBar
            // Calcola percentuale completata
            int percentualeCompletata = (int)(((double)(secondiTotali - secondiRimanenti) / secondiTotali) * 100);
            progressBar.Value = Math.Min(percentualeCompletata, 100);

            // BONUS: Colore della progressbar in base al tempo rimasto
            if (secondiRimanenti < 60)
            {
                // Ultimi 60 secondi โ†’ rosso (urgente!)
                progressBar.ForeColor = Color.Red;
            }
            else if (secondiRimanenti < 300)
            {
                // Ultimi 5 minuti โ†’ arancione
                progressBar.ForeColor = Color.Orange;
            }
            else
            {
                // Tanto tempo โ†’ verde
                progressBar.ForeColor = Color.Green;
            }
        }
    }
}
  1. ๐ŸŽฌ Come Funziona

๐Ÿ“‹ Ciclo Pomodoro:

  1. App si apre in modalitร  LAVORO (sfondo verde, 25:00)
  2. Clicchi Inizia โ†’ il countdown parte
  3. La ProgressBar si riempie man mano
  4. Arriva a 00:00 โ†’ BEEP! MessageBox: "Tempo scaduto!"
  5. Passa in modalitร  PAUSA (sfondo blu, 05:00)
  6. Clicchi Inizia di nuovo โ†’ countdown pausa
  7. Arriva a 00:00 โ†’ BEEP! Torna in modalitร  LAVORO
  8. Il ciclo continua!

Nuovi Concetti

System.Media.SystemSounds.Beep.Play()

Riproduce un suono di sistema

// Suono beep standard
SystemSounds.Beep.Play();

// Altri suoni disponibili:
SystemSounds.Asterisk.Play();     // *
SystemSounds.Exclamation.Play();  // !
SystemSounds.Hand.Play();         // โœ‹
SystemSounds.Question.Play();     // ?

Math.Min() e Math.Max()

Restituisce il valore minimo o massimo tra due numeri

int minore = Math.Min(5, 10);    // 5
int maggiore = Math.Max(5, 10);  // 10

// Uso pratico: limita un valore
progressBar.Value = Math.Min(percentuale, 100);
// Se percentuale = 150, Value sarร  100 (limite massimo)

Const (costanti)

Valori che non cambiano mai durante l'esecuzione

// Dichiarazione costante
private const int TEMPO_LAVORO = 1500;

// Convenzione: NOME_TUTTO_MAIUSCOLO
// Vantaggi: piรน leggibile, se cambi valore รจ in UN solo punto

Esercizio 4: Simulatore Download

Obiettivo

Simula il download di un file con ProgressBar che si riempie e percentuale che sale!

  1. Interfaccia Veloce
  • ProgressBar: progressBar
  • Label: lbl_percentuale (Text = "0%")
  • Label: lbl_stato (Text = "Pronto")
  • Button: btn_download (Text = "๐Ÿ“ฅ Scarica File")
  • Timer: timer (Interval = 100, Enabled = false)
  1. Codice Semplificato

DownloadSimulator.cs

private int percentuale = 0;

private void btn_download_Click(object sender, EventArgs e)
{
    // Reset
    percentuale = 0;
    progressBar.Value = 0;
    lbl_stato.Text = "Download in corso...";

    // Avvia timer
    timer.Start();

    // Disabilita pulsante
    btn_download.Enabled = false;
}

private void timer_Tick(object sender, EventArgs e)
{
    // Incrementa percentuale (random per simulare velocitร  variabile)
    Random rnd = new Random();
    int incremento = rnd.Next(1, 5);  // Da 1 a 4

    percentuale += incremento;

    // Limita a 100
    if (percentuale > 100)
        percentuale = 100;

    // Aggiorna UI
    progressBar.Value = percentuale;
    lbl_percentuale.Text = $"{percentuale}%";

    // Download completato?
    if (percentuale >= 100)
    {
        timer.Stop();
        lbl_stato.Text = "โœ… Download completato!";
        lbl_stato.ForeColor = Color.Green;
        btn_download.Enabled = true;

        MessageBox.Show("File scaricato con successo!", "Completato",
                      MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
}

Esercizio 5: Quiz a Tempo

Obiettivo

Quiz con domande a risposta multipla. Hai 30 secondi per rispondere!

  1. Codice Completo (Semplificato)

QuizATempo.cs

private int tempoRimasto = 30;
private int domandaCorrente = 0;
private int punteggioTotale = 0;

private string[] domande = {
    "Quale linguaggio usiamo?",
    "Quanti millisecondi in 1 secondo?",
    "Che controllo mostra tabelle?"
};

private string[][] opzioni = {
    new string[] { "C#", "Python", "Java", "Ruby" },
    new string[] { "10", "100", "1000", "10000" },
    new string[] { "Label", "TextBox", "DataGridView", "Button" }
};

private int[] risposteCorrette = { 0, 2, 2 }; // Indici delle risposte corrette

private void btn_inizia_Click(object sender, EventArgs e)
{
    domandaCorrente = 0;
    punteggioTotale = 0;
    MostraDomanda();
}

private void MostraDomanda()
{
    if (domandaCorrente >= domande.Length)
    {
        // Quiz finito!
        timer.Stop();
        MessageBox.Show($"Quiz completato!\nPunteggio: {punteggioTotale}/{domande.Length}",
                       "Fine", MessageBoxButtons.OK, MessageBoxIcon.Information);
        return;
    }

    // Mostra domanda
    lbl_domanda.Text = domande[domandaCorrente];

    // Mostra opzioni (4 RadioButton)
    rdb_opzione1.Text = opzioni[domandaCorrente][0];
    rdb_opzione2.Text = opzioni[domandaCorrente][1];
    rdb_opzione3.Text = opzioni[domandaCorrente][2];
    rdb_opzione4.Text = opzioni[domandaCorrente][3];

    // Reset timer
    tempoRimasto = 30;
    progressBar.Maximum = 30;
    progressBar.Value = 30;
    timer.Start();
}

private void timer_Tick(object sender, EventArgs e)
{
    tempoRimasto--;
    progressBar.Value = tempoRimasto;
    lbl_tempo.Text = $"Tempo: {tempoRimasto}s";

    if (tempoRimasto <= 0)
    {
        timer.Stop();
        MessageBox.Show("Tempo scaduto!", "Oops",
                      MessageBoxButtons.OK, MessageBoxIcon.Warning);
        domandaCorrente++;
        MostraDomanda();
    }
}

private void btn_risposta_Click(object sender, EventArgs e)
{
    timer.Stop();

    // Controlla quale RadioButton รจ selezionato
    int rispostaData = -1;
    if (rdb_opzione1.Checked) rispostaData = 0;
    else if (rdb_opzione2.Checked) rispostaData = 1;
    else if (rdb_opzione3.Checked) rispostaData = 2;
    else if (rdb_opzione4.Checked) rispostaData = 3;

    // Verifica correttezza
    if (rispostaData == risposteCorrette[domandaCorrente])
    {
        punteggioTotale++;
        MessageBox.Show("โœ… Risposta corretta!", "Bravo!",
                      MessageBoxButtons.OK, MessageBoxIcon.Information);
    }
    else
    {
        MessageBox.Show("โŒ Risposta sbagliata!", "Oops",
                      MessageBoxButtons.OK, MessageBoxIcon.Error);
    }

    domandaCorrente++;
    MostraDomanda();
}

Riepilogo: Cosa Hai Imparato

โœจ Competenze Acquisite

1๏ธโƒฃ Timer

  • Eseguire codice periodicamente
  • Creare orologi e cronometri
  • Start(), Stop(), Interval

2๏ธโƒฃ ProgressBar

  • Mostrare avanzamento
  • Feedback visivo operazioni
  • Minimum, Maximum, Value

3๏ธโƒฃ DateTime

  • Ottenere data/ora corrente
  • Formattare orari
  • Calcoli con tempo

4๏ธโƒฃ Applicazioni Dinamiche

  • Countdown e timer
  • Simulazioni real-time
  • Quiz interattivi

๐Ÿš€ Prossima Lezione

Hai imparato a creare app dinamiche! Nella prossima lezione scoprirai come creare applicazioni multi-finestra: form di login che aprono dashboard, finestre di dettaglio, dialog personalizzati! ๐ŸชŸ