Nel post precedente abbiamo realizzato una piccola
applicazione che ci dice quanti anni abbiamo. Ho usato l'evento Validating
della TextBox per controllare che l'input dell'utente sia valido (in realtà l'ho
fatto in modo orrendo, come giustamente Marco ho
sottolineato). In questo post vado avanti con il discorso:
- usiamo il controllo ErrorProvider per segnalare
all'utente l'errore
- miglioriamo la validazione con la classe Convert
- diamo una prima occhiata al blocco Try...Catch
Nel codice di ieri, se la validazione falliva, il codice prevedeva un
semplice e.Cancel = true ; senza dare
alcuna comunicazione all'utente. Semplicemente il focus rimane sulla TextBox e il click sul
button btnCalcola non fa nulla. La Study Guide di Lorenzo dice di usare il control
ErrorProvider. Di cosa si tratta? In breve: è un controllo invisibile a
run-time
che dispone di un metodo SetError
(dettagli su MSDN) che permette di mostrare un'icona vicino al
controllo che ha fallito la validazione e un tooltip sopra l'icona con il
messaggio che vogliamo noi. Ok, vediamo di usarlo. Dalla toolbox di VS,
trasciniamo il controllo ErrorProvider, lo chiamiamo errMsg. Io
ho impostato la property BlinkStyle = NeverBlink .
A questo
punto ho scritto il codice dell'evento Validating, migliore rispetto a quello di
ieri:
private void txtBirthYear_Validating(object sender, System.ComponentModel.CancelEventArgs e)
{
int anno;
string msg;
// controllo la lunghezza della property Text della TextBox
if (txtBirthYear.Text.Length != 4)
msg = "L'anno deve essere lungo 4 caratteri!";
try
{
// assegnamento che potrebbe sollevare un'exception
anno = Convert.ToInt32(txtBirthYear.Text);
}
catch
{
// in caso di errore, la validazione fallisce
// e setto il messaggio di errore
msg = "L'anno non è valido!";
}
if (anno < 1880 || anno > System.DateTime.Now.Year)
msg = "L'anno non è valido!";
errMsg.SetError(txtBirthYear, msg);
// attivo l'errore e il focus
// rimane sulla TextBox
if (msg.Length > 0) e.Cancel = true;
}
Qui
c'è già qualcosa che non mi quadra. Ho letto il post di Marco sull'uso della libreria FxCop per la scrittura del buon codice. Una delle regole, la n°4, dice di "evitare
di inizializzare le variabili ai loro valori di default. E' quello che ho fatto
io qui sopra, ma il compilatore mi riporta: "Use of unassigned local
variable 'anno'" (stesso errore per msg), quindi ho dovuto
assegnare dei valori iniziali alle variabili (anno = 0, msg = "").
Mah!
Ho
dichiarato una stringa msg che conterrà l'eventuale
messaggio di errore da mostrare. A questo punto faccio tutti i controlli che
voglio: se c'è qualcosa che non va, in msg memorizzo la stringa
che voglio far vedere all'utente finale. In breve: controllo la lunghezza, come
ieri, controllo che l'anno non sia superiore all'anno in corso e che non sia
minore di 1880. Attenzione: qui non siamo più in VB6, le
conversioni bisogna farsele a mano. txtBirthYear.Text contiene una stringa, per
cui:
try
{
// assegnamento che potrebbe sollevare un'exception
anno = Convert.ToInt32(txtBirthYear.Text);
}
catch
{
// in caso di errore, la validazione fallisce
// e setto il messaggio di errore
msg = "L'anno non è valido!";
}
Attenzione:
il codice è stato incluso in un blocco
Try...Catch per prevenire eventuali assegnamenti che genererebbero errori (se
l'utente scrive "196a", per esempio, o altre stringhe che non possono essere
convertite in intero).
In fondo alla function
Validating, infine, chiamo sempre il metodo SetError
così:
errMsg.SetError(txtBirthYear, msg);
Questa linea di codice serve anche a rimuovere icona+messaggio nel caso in
cui la validazione abbia successo. MSDN dice che: "If the string length is
greater than zero, then the error icon is displayed, and the ToolTip for the
error icon is the error description text. If the string length is zero, the
error icon is hidden.". Quindi se msg.Length == 0, non ho alcun
errore, l'icona e il messaggio spariscono. L'ErrorProvider ha diverse cose
utili:
Se msg.Length > 0, ho un errore, appaiono l'icona e il tooltip.
Il click del btnCalcola invece mi piace di più
così:
private void btnCalcola_Click(object sender, System.EventArgs e)
{
int anno = System.DateTime.Now.Year - Convert.ToInt32(txtBirthYear.Text);
string msg = String.Format("Hai {0} anni!!!", anno.ToString());
MessageBox.Show(msg);
}
Ieri usavamo la concatenazione delle stringhe, oggi usiamo la
classe String. Mi vengono in mente le buone "vecchie"
printf del C-ANSI. Il metodo Format sostituisce {0}
con anno.ToString(). Questo sarà molto utile per la gestione della
localizzazione delle applicazioni: anni fa creai un'applicazione VB6 in
italiano, inglese e spagnolo e la mia gestione della localizzazione fu orribile
(meglio non dirvelo!). Con .NET sarà tutto molto più semplice!
Come ci tengo a dire, anche io sto studiando, perciò più correzioni
avete da farmi, più son contento!
powered by IMHO 1.2