1

I have a Windows forms application written in C#.

I am looking for a way to validate my price textBox so that it only accepts prices in a double format e.g. allowing 0.01 & 1200.00 but provides an error when the user enters characters.

I would except the code to looks similar to

String price = tbx_price.Text.Trim();

if price is not a number
{
   error message
}
else{
...

What method could I use to check if the price string contains only numbers? Please note that I require the user to be able to use decimal places so the '.' character should be allowed.

yoozer8
  • 7,361
  • 7
  • 58
  • 93
Mark Taylforth
  • 187
  • 3
  • 13

3 Answers3

8

Use decimal.TryParse :

decimal d;
if (!decimal.TryParse(price, out d)){
    //Error
}

And if you also want to validate the price (145.255 is invalid):

if (!(decimal.TryParse(price, out d) 
           && d >= 0 
           && d * 100 == Math.Floor(d*100)){
    //Error
}
Ahmed KRAIEM
  • 10,267
  • 4
  • 30
  • 33
  • 1
    Won't it become a problem depending on culture? In some places you write `1,13` while in others you write `1.13`. – Stan May 23 '13 at 15:52
  • 1
    TryParse is the way you want to go. Why? TryParse allows you to convert strings to doubles, int etc. Why is TryParse better than Convert.To? TryParse is fail proof and isn't going to throw exceptions. Simply use this answer, and all you have to do is create a couple of if statements allowing validation. Enjoy C#ing! – Philip Gullick May 23 '13 at 15:54
  • @Steve to overcome that problem, you simply validate the input. You just simply find ',' in the string, and replace with '.' before you tryparse to a double :) – Philip Gullick May 23 '13 at 15:55
  • @PhilipGullick I wouldn't reccommend that, if you can't be sure that the thread culture is the same as the user's culture, instead use the TryParse overload which accepts the number format. – Oliver May 23 '13 at 15:56
  • Exactly what I was thinking. Then you'll have to hack/change current culture to make sure it will work correctly. – Stan May 23 '13 at 15:58
  • 1
    Ah, I forgot that overload :). but the replace still stands and will help him further in learning c# when coming up to new problems. – Philip Gullick May 23 '13 at 15:58
4

You can test this using decimal.TryParse().

For example:

decimal priceDecimal;
bool validPrice = decimal.TryParse(price, out priceDecimal);

If you can't be sure that the thread culture is the same as the user's culture, instead use the TryParse() overload which accepts the culture format (also the number format which you can set to currency):

public bool ValidateCurrency(string price, string cultureCode)
{
    decimal test;
    return decimal.TryParse
       (price, NumberStyles.Currency, new CultureInfo(cultureCode), out test);
}

if (!ValidateCurrency(price, "en-GB"))
{
    //error
}
Oliver
  • 8,794
  • 2
  • 40
  • 60
  • 1
    I think this is a great answer because it takes into account the user culture. There's more than one way to write a price in the world. – aitch-hat Feb 07 '20 at 08:01
0

Besides using the answer marked as accepted in order to avoid the problem with culture about prices, you can always use this

Convert.ToDouble(txtPrice.Text.Replace(".", ","));
Convert.ToDouble(txtPrice.Text.Replace(",", "."));

this will depend how you manage your convertion in your app.

PS: I could not comment the answer because i do not have the neccesary reputation yet.

Matias
  • 708
  • 10
  • 24