|
|||||||
|
|
|
![]() |
|
|
Strumenti |
|
|
#1 |
|
Senior Member
Iscritto dal: Sep 2004
Messaggi: 3967
|
[C#/VS2005]Validazione input utente
Ciao a tutti
Fino ad ora, nei miei piccoli progetti winforms, gestivo la validazione dell'input da parte dell'utente gestendo gli eventi per ogni singolo controllo presente sul form, per esempio per controllare che una textbox non venisse lasciata vuota o accettasse solo valori numerici et similia.. Adesso invece vorrei capire come fare per creare una classe apposita che possa gestirmi queste cose indipendentemente dal tipo di oggetto, soprattutto in considerazione del fatto che normalmente, un'applicazione che sia già poco più di un esempio, può contenere decine di forms. L'ideuzza che ho io sarebbe in pratica: Input utente -> Validazione Validazione = ok -> passa i dati sul db x esempio Validazione = no -> evidenzia il controllo che richiede un input corretto. Sapreste mettermi sulla buona strada? grazie mille RaouL.
__________________
Dai wafer di silicio nasce: LoHacker... il primo biscotto Geek
|
|
|
|
|
|
#2 |
|
Senior Member
Iscritto dal: May 2004
Città: Londra (Torino)
Messaggi: 3692
|
La strategia che considero migliore e' quella di "impedire" il piu' possibile a priori all'utente di digitare qualcosa di sbagliato.
Per ASP.net e per WPF ci sono dei template anche estendibili per scrivere in fase dichiarativa cosa conterra' l'elemento di input. Se per esempio nel WebForm di una pagina ASP.net si istanzia una TextBox e si vuole che contenga solo formule, allora potrai usare il filtro dichiarativo per imporre tale comportamento. Codice:
<asp:TextBox runat="server" ID="TextBox3" />
<ajaxToolkit:FilteredTextBoxExtender ID="ftbe" runat="server"
TargetControlID="TextBox3"
FilterType="Custom, Numbers"
ValidChars="+-=/*()." />
Relativamente a WinForm mi ricordo di avere usato una libreria che permetteva un comportamento simile. Talvolta la fase di validazione dovra comunque essere fatta. Ma direi piu' leggera. In Winform puoi dichiarare per una form/controllo quello che e' il pulsante di Conferma. Al premere del pulsante il Framework scatenera' l'evento Validating su ciascuno dei componenti visuali della form/controllo (Quindi tutte le textbox, etc.) Potrai quindi sottoscriverai questo evento su qualcuno di questi componenti, e il corpo del metodo potra' elevare il fallimento della validazione, cosa che elevera' una Eccezione invece di chiamare il codice del metodo del pulsante di Conferma. Cosa fare con l'eccezione sta poi a te, come per esempio visualizzare una dialog di errore. Per quanto riguarda la strategia da adottare per descrivere il codice di validazione dipende dalla natura delle tue validazioni. Se sono tante e sono tutte simili/uguali ti consiglierei di usare un subclassing dei controlli standard, ovvero di creare dei tuoi controlli con quel paio di validazioni che andrai a pilotare in fase dichiarativa e che potrai estendere con il passare del tempo quando dovessi trovare l'esigenza di nuove validazioni non ancora coperte. Se invece i controlli da validare sono pochi e le validazioni sono tutte diverse e magari cambiano anche a runtime, ti consiglieri di dare un'occhiata al Decorator Pattern.
__________________
Se pensi che il tuo codice sia troppo complesso da capire senza commenti, e' segno che molto probabilmente il tuo codice e' semplicemente mal scritto. E se pensi di avere bisogno di un nuovo commento, significa che ti manca almeno un test. Ultima modifica di gugoXX : 26-05-2009 alle 13:19. |
|
|
|
|
|
#3 |
|
Senior Member
Iscritto dal: Sep 2004
Messaggi: 3967
|
Ciao gugoXX
In generale io faccio così: Parto anche io dal presupposto di cercare di impedire a priori l'inserimento di input non valido anzichè controllarlo successivamente. per fare questo, solitamente uso l'evento KeyPressEventArgs in modo tale che se l'utente si trova su una casella che accetti solo numeri, non possa neanche per sbaglio inserire una lettera (e quindi se ad esempio ho 20 textbox devo gestire 20 eventi KeyPressEventArgs). Quello che a me non piace però, è dover gestire appunto un evento per ogni singolo controllo. Pensavo di generalizzare la validazione almeno per due aspetti: 1) Non lasciare un campo obbligatorio vuoto 2) Avere il focus sull'oggetto dove c'è l'eccezione Stavo ragionando in questi termini: Codice:
public class ProvaValidazione
{
private const string emptyFieldMessage = "CAMPO OBBLIGATORIO";
public static bool IsValid(TextBox t)
{
if(t.Text.Length != 0)
{
SomeErrorProvider.Clear();
return true;
}
else
{
SomeErrorProvider.SetError(t, emptyFieldMessage);
return false;
}
}
}
Infatti se devo validare i dati alla pressione del tasto conferma, se per esempio mi trovassi ad avere 20 textbox, dovrei fare: Codice:
(if(IsValid(txtCognome) && IsValid(txtNome) && blablabla...
__________________
Dai wafer di silicio nasce: LoHacker... il primo biscotto Geek
|
|
|
|
|
|
#4 |
|
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Se i 20 componenti fossero raccolti in una collezione, basterebbe codificare il controllo di validazione in un ciclo.
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) |
|
|
|
|
|
#5 |
|
Senior Member
Iscritto dal: Sep 2004
Messaggi: 3967
|
ciao banryu79
Mmm... alla fine, diciamo che devo controllare che la lunghezza di alcune stringhe non sia pari a zero. usando una collezione, potrei fare: Codice:
List<string> lista = new List<string>();
lista.Add(txtCognome.Text);
lista.Add(txtNome.Text);
lista.Add(comboBoxQualcosa.Text);
...
foreach(string s in lista)
{
if(s.Length == 0)
{
blabla
}
else
{
....
}
}
.... però così poi non potrei capire su quale controllo mettere il focus perchè è vuoto.
__________________
Dai wafer di silicio nasce: LoHacker... il primo biscotto Geek
Ultima modifica di RaouL_BennetH : 26-05-2009 alle 15:29. |
|
|
|
|
|
#6 |
|
Senior Member
Iscritto dal: Sep 2004
Messaggi: 3967
|
Forse ho trovato:
Codice:
List<Control> controlList = new List<Control>();
controlList.Add(txtCognome);
controlList.Add(comboBoxQualcosa);
controlList.Add(txtNome);
for(int i = 0; i < controlList.Count; ++i)
{
if(controlList[i].Text.Length == 0)
{
SomeErrorProvider.SetError(controlList[i], "errore");
}
}
__________________
Dai wafer di silicio nasce: LoHacker... il primo biscotto Geek
|
|
|
|
|
|
#7 |
|
Senior Member
Iscritto dal: Sep 2004
Messaggi: 3967
|
mmm.. ho notato una cosa però...
mi basta che uno solo dei campi sia vero ed il controllo si blocca. Cioè, se sono tutti vuoti, me lo segnala correttamente... se invece ne ho solo uno vuoto, non me lo segnala..
__________________
Dai wafer di silicio nasce: LoHacker... il primo biscotto Geek
|
|
|
|
|
|
#8 | |
|
Senior Member
Iscritto dal: Oct 2007
Città: Padova
Messaggi: 4131
|
Quote:
Nel codice che hai postato in precedenza si vede che nel caso un controllo sia valido, chiami il metodo Clear; magari dipende da questo.
__________________
As long as you are basically literate in programming, you should be able to express any logical relationship you understand. If you don’t understand a logical relationship, you can use the attempt to program it as a means to learn about it. (Chris Crawford) |
|
|
|
|
|
|
#9 | |
|
Senior Member
Iscritto dal: Dec 2004
Messaggi: 3210
|
Quote:
Perchè creare una List ? Non è più semplice un foreach a livello di container ? Se vuoi restringere i controlli sull'input utente solo ad alcuni controls specifici ci sono anche altre vie, come ad esempio l'uso dei Tag... |
|
|
|
|
|
|
#10 | |
|
Senior Member
Iscritto dal: Sep 2004
Messaggi: 3967
|
Quote:
Ho pensato ad una lista perchè ho fatto questa considerazione: In un container potrei avere anche controlli sui quali non devo verificarne il contenuto, perchè magari non sono campi obbligatori. Con una lista a disposizione invece posso decidere appunto quali devono essere verificati. Di conseguenza, se usassi un foreach sul container, inevitabilmente mi fa il check 'per ogni' controllo presente. Oltre a questo, dovrei anche andare a specificare cose del tipo: "se il controllo è un textbox" "se il controllo è un combobox" Credo di aver fatto un altro piccolo passo in avanti (spero); Sia ben chiaro che sono ben accette tutte le critiche e i suggerimenti Codice:
public class ValidatoreElementare()
{
public static bool CampiObbligatoriOk(List<Control> controlList, ErrorProvider helper)
{
bool fieldsOk = true;
helper.Clear();
for (int i = 0; i < controlList.Count; ++i)
{
controlList[i].BackColor = Color.White;
if (controlList[i].Text.Length == 0)
{
helper.SetError(controlList[i], "CAMPO OBBLIGATORIO");
controlList[i].BackColor = Color.LightYellow;
fieldsOk = false;
}
}
return fieldsOk;
}
//da un form
List<Control> ls = new List<Control>();
ls.Add(txtCognome);
ls.Add(txtNome);
ls.Add(cmbProfessione);
return ValidatoreElementare.CampiObbligatoriOk(ls, formErrorProvider);
__________________
Dai wafer di silicio nasce: LoHacker... il primo biscotto Geek
|
|
|
|
|
|
|
#11 | |
|
Senior Member
Iscritto dal: Dec 2004
Messaggi: 3210
|
Quote:
Esempio : Ho vari controlli, ma solo in quelli che prevedo debbano essere Not Null vado a scrivere nella proprietà Tag = NotNull. Codice:
foreach (Control C in this.Controls) {
if ((string)C.Tag == "NotNull") {
if (C.Text == "") {
C.BackColor = Color.Red;
MessageBox.Show(C.GetType() + " - " + C.Name + " Non può essere vuoto !");
//... ecc ...
//... ecc ...
}
}
}
|
|
|
|
|
|
|
#12 |
|
Senior Member
Iscritto dal: Sep 2004
Messaggi: 3967
|
Capito
Ragionerò anche sul tuo suggerimento. Per il momento grazie
__________________
Dai wafer di silicio nasce: LoHacker... il primo biscotto Geek
|
|
|
|
|
| Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 11:17.




















