Sensing a decimal in a textBox - c#

I'm developing a kind of calculator for the Windows Phone.
It doesn't need to use decimals. (who needs .39 of a brick)
How would I detect that there is a decimal in a string or a textBox?
EDIT: Thanks, #Bala R and #Afnan. But what I was after was something that filtered out letters as well. My answer's below.

Modyfying the Bala R code gives
private void textBox1_TextChanged(object sender, EventArgs e)
{
if (textBox1.Text.Contains(".") || textBox1.Text.Contains(","))
textBox1.Text = textBox1.Text.Replace(".", string.Empty).Replace(",", string.Empty);
}
this will remove the invalid characters that are entered as the input is written

I think that you need to check whether the value is a valid decimal value.
Use TryParse method:
decimal value;
string textValue = textBox.Text;
bool isDecimal = decimal.TryParse(textValue, out value)

You can use this to see if there is a "period" in string
bool hasDecimal = textBox.Text.Contains(".")
but more than one period would be bad for a decimal value.

Here's what I found works the best:
bool bNeedToUpdate = false;
StringBuilder szNumbersOnly = new StringBuilder();
TextBox textSource = sender as TextBox;
if (null == textSource)
return;
foreach (char ch in textSource.Text)
{
if (("0123456789").Contains(ch.ToString()))
{
szNumbersOnly.Append(ch);
}
else
{
bNeedToUpdate = true;
}
}
if (bNeedToUpdate)
{
textSource.Text = szNumbersOnly.ToString();
textSource.SelectionStart = szNumbersOnly.Length;
}
I swiped this answer off Erin Fleck, a forums moderator that answered this similar question.
#Afnan gets the green check because he/she/it answered my original question.

Related

c# dictionary using textbox to select index from datagridview [duplicate]

I'm new with C#, I have some basic knowledge in Java but I can't get this code to run properly.
It's just a basic calculator, but when I run the program VS2008 gives me this error:
I did almost the same program but in java using JSwing and it worked perfectly.
Here's the form of c#:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace calculadorac
{
public partial class Form1 : Form
{
int a, b, c;
String resultado;
public Form1()
{
InitializeComponent();
a = Int32.Parse(textBox1.Text);
b = Int32.Parse(textBox2.Text);
}
private void button1_Click(object sender, EventArgs e)
{
add();
result();
}
private void button2_Click(object sender, EventArgs e)
{
substract();
result();
}
private void button3_Click(object sender, EventArgs e)
{
clear();
}
private void add()
{
c = a + b;
resultado = Convert.ToString(c);
}
private void substract()
{
c = a - b;
resultado = Convert.ToString(c);
}
private void result()
{
label1.Text = resultado;
}
private void clear()
{
label1.Text = "";
textBox1.Text = "";
textBox2.Text = "";
}
}
What can be the problem? Is there a way to solve it?
PS: I also tried
a = Convert.ToInt32(textBox1.text);
b = Convert.ToInt32(textBox2.text);
and it didn't work.
The error means that the string you're trying to parse an integer from doesn't actually contain a valid integer.
It's extremely unlikely that the text boxes will contain a valid integer immediately when the form is created - which is where you're getting the integer values. It would make much more sense to update a and b in the button click events (in the same way that you are in the constructor). Also, check out the Int.TryParse method - it's much easier to use if the string might not actually contain an integer - it doesn't throw an exception so it's easier to recover from.
I ran into this exact exception, except it had nothing to do with parsing numerical inputs. So this isn't an answer to the OP's question, but I think it's acceptable to share the knowledge.
I'd declared a string and was formatting it for use with JQTree which requires curly braces ({}). You have to use doubled curly braces for it to be accepted as a properly formatted string:
string measurements = string.empty;
measurements += string.Format(#"
{{label: 'Measurement Name: {0}',
children: [
{{label: 'Measured Value: {1}'}},
{{label: 'Min: {2}'}},
{{label: 'Max: {3}'}},
{{label: 'Measured String: {4}'}},
{{label: 'Expected String: {5}'}},
]
}},",
drv["MeasurementName"] == null ? "NULL" : drv["MeasurementName"],
drv["MeasuredValue"] == null ? "NULL" : drv["MeasuredValue"],
drv["Min"] == null ? "NULL" : drv["Min"],
drv["Max"] == null ? "NULL" : drv["Max"],
drv["MeasuredString"] == null ? "NULL" : drv["MeasuredString"],
drv["ExpectedString"] == null ? "NULL" : drv["ExpectedString"]);
Hopefully this will help other folks who find this question but aren't parsing numerical data.
If you are not validating explicitly for numbers in the text field, in any case its better to use
int result=0;
if(int.TryParse(textBox1.Text,out result))
Now if the result is success then you can proceed with your calculations.
Problems
There are some possible cases why the error occurs:
Because textBox1.Text contains only number, but the number is too big/too small
Because textBox1.Text contains:
a) non-number (except space in the beginning/end, - in the beginning) and/or
b) thousand separators in the applied culture for your code without specifying NumberStyles.AllowThousands or you specify NumberStyles.AllowThousands but put wrong thousand separator in the culture and/or
c) decimal separator (which should not exist in int parsing)
NOT OK Examples:
Case 1
a = Int32.Parse("5000000000"); //5 billions, too large
b = Int32.Parse("-5000000000"); //-5 billions, too small
//The limit for int (32-bit integer) is only from -2,147,483,648 to 2,147,483,647
Case 2 a)
a = Int32.Parse("a189"); //having a
a = Int32.Parse("1-89"); //having - but not in the beginning
a = Int32.Parse("18 9"); //having space, but not in the beginning or end
Case 2 b)
NumberStyles styles = NumberStyles.AllowThousands;
a = Int32.Parse("1,189"); //not OK, no NumberStyles.AllowThousands
b = Int32.Parse("1,189", styles, new CultureInfo("fr-FR")); //not OK, having NumberStyles.AllowThousands but the culture specified use different thousand separator
Case 2 c)
NumberStyles styles = NumberStyles.AllowDecimalPoint;
a = Int32.Parse("1.189", styles); //wrong, int parse cannot parse decimal point at all!
Seemingly NOT OK, but actually OK Examples:
Case 2 a) OK
a = Int32.Parse("-189"); //having - but in the beginning
b = Int32.Parse(" 189 "); //having space, but in the beginning or end
Case 2 b) OK
NumberStyles styles = NumberStyles.AllowThousands;
a = Int32.Parse("1,189", styles); //ok, having NumberStyles.AllowThousands in the correct culture
b = Int32.Parse("1 189", styles, new CultureInfo("fr-FR")); //ok, having NumberStyles.AllowThousands and correct thousand separator is used for "fr-FR" culture
Solutions
In all cases, please check the value of textBox1.Text with your Visual Studio debugger and make sure that it has purely-acceptable numerical format for int range. Something like this:
1234
Also, you may consider of
using TryParse instead of Parse to ensure that the non-parsed number does not cause you exception problem.
check the result of TryParse and handle it if not true
int val;
bool result = int.TryParse(textbox1.Text, out val);
if (!result)
return; //something has gone wrong
//OK, continue using val
In my case I forgot to put double curly brace to escape. {{myobject}}
You may encounter this exception when you use a string formatter with invalid bracket syntax.
// incorrect
string.Format("str {incorrect}", "replacement")
// correct
string.Format("str {1}", "replacement")
You have not mentioned if your textbox have values in design time or now. When form initializes text box may not hae value if you have not put it in textbox when during form design. you can put int value in form design by setting text property in desgin and this should work.
it was my problem too ..
in my case i changed the PERSIAN number to LATIN number and it worked.
AND also trime your string before converting.
PersianCalendar pc = new PersianCalendar();
char[] seperator ={'/'};
string[] date = txtSaleDate.Text.Split(seperator);
int a = Convert.ToInt32(Persia.Number.ConvertToLatin(date[0]).Trim());
I had a similar problem that I solved with the following technique:
The exception was thrown at the following line of code (see the text decorated with ** below):
static void Main(string[] args)
{
double number = 0;
string numberStr = string.Format("{0:C2}", 100);
**number = Double.Parse(numberStr);**
Console.WriteLine("The number is {0}", number);
}
After a bit of investigating, I realized that the problem was that the formatted string included a dollar sign ($) that the Parse/TryParse methods cannot resolve (i.e. - strip off). So using the Remove(...) method of the string object I changed the line to:
number = Double.Parse(numberStr.Remove(0, 1)); // Remove the "$" from the number
At that point the Parse(...) method worked as expected.

Calculator - thousand separator by comma in c#

private void TextBox_TextChanged(object sender, EventArgs e)
{
string value = TextBox.Text.Replace(",", "");
double dbl;
if (double.TryParse(value, out dbl))
{
TextBox.TextChanged -= TextBoxTextChanged;
TextBox.Text = string.Format("{0:#,#0}", dbl);
TextBox.SelectionStart = TextBox.Text.Length;
TextBox.TextChanged += TextBoxTextChanged;
}
}
I used above code for making Calculator. I want to get results comma with decimal value. I want to type 1,234.1234 in the
textBox, but I can not type 1,234.1234 in the Text Box. I mean comma with decimal value not getting.
Can anybody kindly please help me to solve this problem ?
You have to provide a Culture that uses . as thousands sign.
Normally you want to use the users current culture.
double.TryParse(value, System.Globalization.NumberStyles.Number, System.Globalization.CultureInfo.CurrentCulture, out dbl)
Try this:
int value = 300000
String.Format("{0:#,###0}", value);
// will return 300,000
http://msdn.microsoft.com/en-us/library/system.string.format.aspx

Bool test on a string gives unexpected result

This should be self explanatory. I am trying to detect if the first char of the string foo is a negative sign '-'. This is just a test code to test it.
private void button1_Click(object sender, EventArgs e)
{
string foo = textBox1.Text;
bool negativeValue = foo[1]==('-');
//bool negativeValue = foo[1].Equals ('-');
if (negativeValue == true)
{
label1.Text = "First char is negative !";
}
else if (negativeValue == false)
{
label1.Text = "First char is not negative !";
}
}
The result is always false even if the first char in the text box is '-'. Why?
Index lookup in C# is zero-based. So you should call:
foo[0] == ('-')
Using 1 will lookup the second character.
EDIT: Also as an alternative (and perhaps more clear) you can always use:
foo.StartsWith("-")
That should work no matter how inebriated you are. :)
(Also, consider trimming the text input if you want to avoid excessive/accidental preceding spaces from user input)
You are using wrong index.With 1 you are actually referring to 2nd character
Use 0
bool negativeValue = foo[0]==('-');

Convert currency string to decimal?

Objective
Sort a string that is displaying currency data like this $1,995.94 numerically in a set of data.
Code
I'm currently using the below code sample to convert the string value to decimal so that I can sort it properly.
if (sortBy == "checkAmount")
{
StringBuilder sb = new StringBuilder();
foreach (var c in Convert.ToString(p.GetType().GetProperty(sortBy).GetValue(p, null)))
{
if (!char.IsDigit(c) && c != '.') { continue; }
sb.Append(c);
}
return Convert.ToDecimal(sb.ToString());
}
else
{
return p.GetType().GetProperty(sortBy).GetValue(p, null);
}
Problem
What's a better way of doing this? It works, and that's cool, but it's not very elegant.
Final Solution
The answer provided by Servy works as expected, and I used that implementation for a while, but a colleague and I found an even better way so I'm documenting it here. BTW, I ended up using this solution in the end.
decimal.Parse(input, NumberStyles.AllowCurrencySymbol | NumberStyles.Number);
How about this, but only works for one string value. So you need to get your string split by $ and then do the conversion while saving into the array or list
using System.Globalization;
//rest of your code
string str = "$50,550.20";
decimal decval;
bool convt = decimal.TryParse(str, NumberStyles.Currency,
CultureInfo.CurrentCulture.NumberFormat, out decval);
if (convt)
Console.WriteLine(decval);
Console.ReadLine();
Here is a simpler solution:
public static decimal ToDecimal(this string str)
{
return decimal.Parse(str, NumberStyles.Currency);
}
and the unit test:
[Test]
public void ToDecimal_Convert_String_To_Decimal()
{
Assert.AreEqual(1234M, "1234".ToDecimal());
Assert.AreEqual(-1234.56M, "$(1,234.56)".ToDecimal());
Assert.AreEqual(1234.56M, "$1,234.56".ToDecimal());
}
Here is a method that most closely resembles the code you've provided
public static decimal Parse(string input)
{
return decimal.Parse(Regex.Replace(input, #"[^\d.]", ""));
}
Here is an option that will support negative numbers, and will stop if it finds a second period value, thus reducing the number of strings it returns that are not valid decimal values. It also has a few other modifications not seen in the OP to handle additional cases your current code doesn't.
public static decimal Parse(string input)
{
return decimal.Parse(Regex.Match(input, #"-?\d{1,3}(,\d{3})*(\.\d+)?").Value);
}
decimal amount = decimal.Parse("$123,456.78",
NumberStyles.AllowCurrencySymbol |
NumberStyles.AllowThousands |
NumberStyles.AllowDecimalPoint);
works for all culture:
var d = decimal.Parse("$497.7", NumberStyles.Currency, CultureInfo.CreateSpecificCulture("us-US").NumberFormat);
Console.WriteLine(d);
public static decimal ToDecimalFromStringDecimalOrMoneyFormattedDecimal(this string s)
{
try
{
return decimal.Parse(s);
}
catch
{
var numberWithoutMoneyFormatting = Regex.Replace(s, #"[^\d.-]", "");
return decimal.Parse(numberWithoutMoneyFormatting);
}
}
[Test]
public void Test_ToDecimalFromStringDecimalOrMoneyFormattedDecimal()
{
Assert.That("$ 500".ToDecimalFromStringDecimalOrMoneyFormattedDecimal() == (decimal)500);
Assert.That("R -500".ToDecimalFromStringDecimalOrMoneyFormattedDecimal() == (decimal)-500);
Assert.That("-$ 500".ToDecimalFromStringDecimalOrMoneyFormattedDecimal() == (decimal)-500);
Assert.That("P 500.90".ToDecimalFromStringDecimalOrMoneyFormattedDecimal() == (decimal)500.9);
Assert.That("$ -50 0,090,08.08".ToDecimalFromStringDecimalOrMoneyFormattedDecimal() == (decimal)-50009008.08);
}
We can try to use decimal.TryParse to cast the currency string value to a decimal number.
NumberStyles:use NumberStyles.Currency which indicates that all styles except AllowExponent and AllowHexSpecifier are used. This is a composite number style.
CultureInfo: we need to set the right culture of currency which align with your currency value.
For this example, $20,000.00 is USA currency we can try to use English (USA) for that, on the other hand 20,000.00€ is euro currency we can try to use English (Ireland) that uses the euro currency.
decimal.TryParse("20,000.00€", NumberStyles.Currency ,CultureInfo.CreateSpecificCulture("en-IE"), out var euro);
Console.WriteLine(euro);
decimal.TryParse("$20,000.00", NumberStyles.Currency ,CultureInfo.CreateSpecificCulture("en-us"), out var dollar);
Console.WriteLine(dollar);
c# online

Converting string to int using C#

I am using C# and I want to convert a string to int to verify name. For example ** or 12 is not a name. I just want to convert the string into ASCII values and then will verify the name. How do I do that?
Converting back and forth is simple:
int i = int.Parse("42");
string s = i.ToString();
If you do not know that the input string is valid, use the int.TryParse() method.
From what I understand, you want to verify that a given string represents a valid name? I'd say you should probably provide more details as to what constitutes a valid name to you, but I can take a stab at it. You could always iterate over all the characters in the string, making sure they're letters or white space:
public bool IsValidName(string theString)
{
for (int i = 0; i < theString.Length - 1; i++)
{
if (!char.IsLetter(theString[i]) && !char.IsWhiteSpace(theString[i]))
{
return false;
}
}
return true;
}
Of course names can have other legitimate characters, such as apostrophe ' so you'd have to customize this a bit, but it's a starting point from what I understand your question truly is. (Evidently, not all white space characters would qualify as acceptable either.)
There multiple ways to convert:
try
{
string num = "100";
int value;
bool isSuccess = int.TryParse(num, out value);
if(isSuccess)
{
value = value + 1;
Console.WriteLine("Value is " + value);
}
}
catch (FormatException e)
{
Console.WriteLine(e.Message);
}
It's not clear to me what you're trying to do, but you can get the ASCII codes for a string with this code:
System.Text.Encoding.ASCII.GetBytes(str)

Categories