2015-09-20 21 views
10

Sto usando WinForm. Ho una casella di testo e un pulsante.Validate currency currency text

Obiettivo: il pulsante deve confermare se la casella di testo è un formato di valuta. Se la casella di testo è un formato di valuta, un messaggio dovrebbe visualizzare il formato di valuta. In caso contrario, un messaggio dovrebbe visualizzare il formato errato Errore.

Esempio di formato di valuta:

$ 1,234.00

$ 12,345.00

$ 123,000.00

$ 1,00

Aggiornamento:

Questo è quello che avevo, ma questo è sbagliato.

Private void button3_Click(object sender, EventArgs e) 
    {  
     currencyTextbox = Convert.ToString(textBox4.Text); 

     string money = currencyTextbox; 

     string s = currencyTextbox; 
     float f; 
     if (float.TryParse(s, NumberStyles.AllowCurrencySymbol 
      | NumberStyles.AllowDecimalPoint | NumberStyles.AllowThousands, 
      CultureInfo.GetCultureInfo("en-US"), out f)) 
     { 
      MessageBox.Show("Ok"); 
     } 
     else 
     { 
      MessageBox.Show("Wrong"); 
     } 
    } 

Casi di test:

$ 12,00 - OK

$ 12.000 - OK

$ 12,3,00 - OK - (valido)

$ 12,3,00 # - Sbagliato

risposta

4

Un certo numero (decimal in questo caso) non è lo stesso della sua rappresentazione di stringa (come valuta in questo caso). Ecco perché devi prima analizzare l'input da un punto di vista della stringa (il formato è soddisfatto?) E poi da uno numerico. Ci sono alcuni modi per eseguire l'analisi in una volta sola (come proposto in altre risposte), sebbene non forniscano la determinazione che si sta cercando (vale a dire, è una valuta o no, intesa come i meri numeri sono sbagliati).

codice di esempio:

private void btn_Click(object sender, EventArgs e) 
{ 
    //Note: ideally, curCulture shouldn't be defined here (but globally or 
    //passed as argument), but otherwise my code would be somehow incomplete. 
    CultureInfo curCulture = new CultureInfo("en-US", true); 

    bool isOK = false; 
    string[] temp = totalTextBox.Text.Trim().Split(new string[] { curCulture.NumberFormat.CurrencySymbol }, StringSplitOptions.None); 
    if (temp.Length == 2 && temp[0].Trim().Length == 0) 
    { 
     decimal outVal = 0m; 
     if (decimal.TryParse(temp[1], out outVal)) isOK = true; 
    } 

    MessageBox.Show(isOK ? "currency format" : "error wrong format"); 

} 

nota un paio di cose:

  • curCulture si prevede di tenere il formato desiderato (si potrebbe anche conto per le diverse culture/valute/formati). Dal tuo esempio, sembra che tu voglia : CultureInfo curCulture = new CultureInfo("en-US", true);.
  • L'analisi della stringa di input può essere complessa come richiesto. Ad esempio: nel codice postato, mi sto anche assicurando che il simbolo della valuta si trovi nella prima posizione.

---- UPDATE (che rappresentano problemi di analisi decimali con separatori di migliaia)

Dopo aver confermato che le proposte Decimal.TryParse (e altri approcci equivalenti) non fornire ciò che ci si aspetta quando separatori di migliaia (gruppo separatori), ho deciso di scrivere il codice qui sotto che si occupa di questo tipo di problemi. In ogni caso, tenete presente che non sono troppo esperto in queste situazioni (cioè, gestendo gli input decimali sbagliati tenendo conto di migliaia di separatori) ed è per questo che non sono sicuro se esistano modi più efficienti per affrontare questo problema (sebbene la proposta l'analisi è certamente veloce).

private void btn_Click(object sender, EventArgs e) 
{ 
    //Note: ideally, curCulture shouldn't be defined here (but globally or 
    //passed as argument), but otherwise my code would be somehow incomplete. 
    CultureInfo curCulture = new CultureInfo("en-US", true); 

    bool isOK = false; 
    string[] temp = totalTextBox.Text.Trim().Split(new string[] { curCulture.NumberFormat.CurrencySymbol }, StringSplitOptions.None); 
    if (temp.Length == 2 && temp[0].Trim().Length == 0) 
    { 
     isOK = isDecimalOK(temp[1], curCulture); 
    } 

    MessageBox.Show(isOK ? "currency format" : "error wrong format"); 
} 

private bool isDecimalOK(string inputString, CultureInfo curCulture) 
{ 
    bool isOK = false; 

    string[] temp = inputString.Split(new string[] { curCulture.NumberFormat.CurrencyDecimalSeparator }, StringSplitOptions.None); 
    if (temp.Length > 2) return isOK; 

    int outVal0 = 0; 
    if (!int.TryParse(temp[0], NumberStyles.AllowThousands, curCulture, out outVal0)) return isOK; 
    else if (analyseThousands(temp[0], curCulture)) 
    { 
     isOK = (temp.Length == 2 ? int.TryParse(temp[1], NumberStyles.Integer, curCulture, out outVal0) : true); 
    } 

    return isOK; 
} 

private bool analyseThousands(string intInput, CultureInfo curCulture) 
{ 

    string[] temp2 = intInput.Split(new string[] { curCulture.NumberFormat.CurrencyGroupSeparator }, StringSplitOptions.None); 

    if (temp2.Length >= 2) 
    { 
     if (temp2[0].Trim().Length == 0) return false; 
     else 
     { 
      for (int i2 = 1; i2 < temp2.Length; i2++) 
      { 
       if (!curCulture.NumberFormat.CurrencyGroupSizes.Contains(temp2[i2].Length)) return false; 
      } 
     } 
    } 

    return true; 
} 
+0

Ciao grazie per aver spiegato. Questo codice mi dà una riga di errore rossa sotto {curCulture, come posso renderlo valido –

+0

@LearningToCode Lo sto spiegando nei miei commenti sotto il codice: definiscilo come desideri.Certo che 'curCulture = new CultureInfo (" en-US ");' è ciò che sto cercando. Scrivi questa riga sopra bool isOK = false; modificherà subito la mia risposta per ogni evenienza. – varocarbas

+0

Forse l'ho scritto male. Ecco come l'ho scritto :: {curCulture = new Cultur eInfo ("en-US"). NumberFormat.CurrencySymbol}, StringSplitOptions.None); –

3

Per verificare il formato è possibile provare a analizzarlo in virgola mobile in questo modo:

 string s = "$123.78"; 
     float f; 
     if (float.TryParse(s, NumberStyles.Any, CultureInfo.GetCultureInfo("en-US"), out f)) 
     { 
      // OK 
     } 
     else 
     { 
      // WRONG 
     } 
+0

Ho provato questo. Questo mi dà un errore. Questo codice accetta $ 12,3,00 che non è vero. –

+0

Si prega di guardare il secondo parametro del metodo TryParse, ho usato "Qualsiasi", ma consentirà tali numeri anormali. Metti lì NumberStyles.AllowCurrencySymbol | NumberStyles.AllowDecimalPoint invece di Any e guarda il risultato – Spawn

+0

Il codice sembra quasi funzionare. Questi sono i casi di test $ 11 Corretto $ 11.00-corretta $ 11,000.00-sbagliato $ 11.000 sbagliato $ 11,00-sbagliato –

1

Prova questo, dovrebbe essere il lavoro

string money = "$12,345.00"; 
float f; 
if (float.TryParse(money, NumberStyles.Currency, CultureInfo.GetCultureInfo("en-US"), out f)) 
{ 
    // valid 
} 
else 
{ 
    // invalid 
} 

informazioni di debug: enter image description here

uscita:

enter image description here

+0

Perché votare giù? :( –

+0

Penso che qualcuno abbia votato perché era simile ad un'altra risposta.Ho testato questo codice e non è valido.Questo codice accetta: 22,2.3 @ X-TECH –

+0

Ho anche controllato sulla mia macchina, funziona 100 % correttamente –

4

Si può provare a usare espressioni regolari:

var moneyR = new Regex(@"^\$(((\d{1,3},)+\d{3})|\d+)(\.\d{2}){0,1}$"); 
if (moneyR.IsMatch(yourValue)) 
{ 
    MessageBox.Show("Ok"); 
} 
else 
{ 
    MessageBox.Show("Wrong"); 
}