MaskedTextBox Currency Input Mask Limits - c#

Im trying to make a Custom Input Mask for currency in Visual Studio 2013
But, this type of mask has a limit: 9999,00.
I can't write numbers like 99999999,00.
I want a mask that works with any amount of numbers
Is it possible?

The standard way of applying the mask via Regular Expresions is detailed in Microsoft documentation: https://msdn.microsoft.com/en-us/library/ms234064.aspx Pertinent to your case it could be something like: $\d{9}.00 Hope this may help.

This worked for me. Instead of creating a custom mask, create a custom maskedTextbox.
Even with the correct mask, the delivered maskedTextBox is difficult for users to enter data. The currencyTextbox automatically formats/shifts the entered values.
https://blogs.msdn.microsoft.com/irenak/2006/03/21/sysk-87-a-better-maskedtextbox-for-currency-fields/
Once you add that class to your project, you'll see the currencyTextBox appear in your toolbox. Then just set a mask for it depending on how large a dollar value you want to store. According to the author, you use all 0s, I personally used "$000,000.00"

//Crie um textbox com o name txt_valor e atribua os eventos KeyPress,KeyUp e
// Leave e uma string valor;
string valor;
private void txt_valor_KeyPress(object sender, KeyPressEventArgs e)
{
if (!Char.IsDigit(e.KeyChar) && e.KeyChar != Convert.ToChar(Keys.Back))
{
if (e.KeyChar == ',')
{
e.Handled = (txt_valor.Text.Contains(","));
}
else
e.Handled = true;
}
}
private void txt_valor_Leave(object sender, EventArgs e)
{
valor = txt_valor.Text.Replace("R$", "");
txt_valor.Text = string.Format("{0:C}", Convert.ToDouble(valor));
}
private void txt_valor_KeyUp(object sender, KeyEventArgs e)
{
valor = txt_valor.Text.Replace("R$","").Replace(",","").Replace(" ","").Replace("00,","");
if(valor.Length == 0)
{
txt_valor.Text = "0,00"+valor;
}
if(valor.Length == 1)
{
txt_valor.Text = "0,0"+valor;
}
if(valor.Length == 2)
{
txt_valor.Text = "0,"+valor;
}
else if(valor.Length >= 3)
{
if(txt_valor.Text.StartsWith("0,"))
{
txt_valor.Text = valor.Insert(valor.Length - 2,",").Replace("0,","");
}
else if(txt_valor.Text.Contains("00,"))
{
txt_valor.Text = valor.Insert(valor.Length - 2,",").Replace("00,","");
}
else
{
txt_valor.Text = valor.Insert(valor.Length - 2,",");
}
}
valor = txt_valor.Text;
txt_valor.Text = string.Format("{0:C}", Convert.ToDouble(valor));
txt_valor.Select(txt_valor.Text.Length,0);
}

Related

FormatException when parsing decimals

I'm working on a code to do billing. This is a small portion of my code:
private void NightsLabel_KeyPress(object sender, KeyPressEventArgs e)
{
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar) && e.KeyChar != '.')
{
e.Handled = true;
}
if (e.KeyChar == '.' && (sender as TextBox).Text.IndexOf('.') > -1)
{
e.Handled = true;
}
}
private void TotalButton_Click(object sender, EventArgs e)
{
RoomChargeLabel.Text = (Convert.ToInt64(NightRateLabel.Text) + Convert.ToInt64(NightsLabel.Text)).ToString();
}
I am struggling when I hit the Total Button Click void. Whenever I enter numbers that have decimals in them, it gives me an error:
System.FormatException: "Input string was not in a correct format".
Whenever I use whole numbers instead, it works just fine but I need to figure out why I can't do decimals.
Please help! :)
You are using Convert.ToInt64(NightRateLabel.Text), you should Use Convert.ToDouble(NightRateLabel.Text)
Or you can do a twin transform check
using System;
public class Program
{
public static void Main()
{
var doubleVal = "123123";
object fomattedValue = null;
try {
fomattedValue = Convert.ToInt64(doubleVal);
} catch {
fomattedValue = Convert.ToDouble(doubleVal);
}
Console.Write(fomattedValue.ToString());
}
}
As the others pointed out, the reason you are getting an error is because parsing a long (Int64) doesn't support decimal numbers:
// Only supports whole numbers, throws an exception for decimal places!
(Convert.ToInt64(NightRateLabel.Text) + Convert.ToInt64(NightsLabel.Text)).ToString();
I'm guessing NightRateLabel.Text is actually a currency (money) value. In that case, you should use decimal:
var nightRate = decimal.Parse(NightRateLabel.Text)
You can also handle failures more gracefully by using TryParse:
// You can inline this (remove var success = ...) of course, but I'm being verbose to demonstrate:
var success = decimal.TryParse(NightRateLabel.Text, out var nightRate);
if (!success)
{
// Handle parsing error gracefully: Show feedback to user, etc.
}
else
{
// Do something with nightRate
}

TextBox keypress event handling for decimals for a range 0 to 9999999999.99

I need a textbox keypress handler which handles a decimal input range of 0 to 9999999999.99 value. I have this code below but is not serving the purpose. With it I cannot enter decimals after 10 digits.
public static void NumericWithDecimalTextBox_KeyPress(object sender, KeyPressEventArgs e)
{
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar) &&
(e.KeyChar != '.'))
{
e.Handled = true;
}
TextBox textBox = sender as TextBox;
string[] parts = textBox.Text.Split('.');
// only allow one decimal point
if (((e.KeyChar == '.') && (textBox.Text.IndexOf('.') > -1)) || (!char.IsControl(e.KeyChar) && ((parts[0].Length >= 10))))
{
e.Handled = true;
}
}
You could simplify the process by having the data validated, along the lines of:
public static void NumericWithDecimalTextBox_KeyPress(object sender, KeyPressEventArgs e)
{
var textBox = sender as TextBox;
var enteredValue = textBox.Text;
var decimalValue = 0M;
if (decimal.TryParse(enteredValue, out decimalValue) && ValueIsWithinRange(decimalValue, 0M, 9999999999.99M))
{
Model.ThePropertyStoringTheValue = decimalValue; // wherever you need to store the value
}
else
{
// Inform the user they have entered invalid data (i.e. change the textbox background colour or show a message box)
}
}
private bool ValueIsWithinRange(decimal valueToValidate, decimal lower, decimal upper)
{
return valueToValidate >= lower && valueToValidate <= upper
}
That way, if the value is valid, it is written to the model (following good MVC design practices) and if it is invalid, the user is informed with a message that would allow them to make corrections (e.g. "the value you have entered isn't a valid decimal" or "the value must not be negative" etc.)

how to calculate tow numbers in textbox instantly and the result chaged when i delete numbers?

how to calculate tow numbers in textbox instantly and the result chaged when i delete numbers from any textbox??
this is my code
private void expenses_KeyDown(object sender, KeyEventArgs e)
{
if (expenses.Text != string.Empty)
{
decimal Pprice = Convert.ToDecimal(buyTotal.Text);
decimal expens = Convert.ToDecimal(expenses.Text);
decimal final = Pprice + expens;
buyTotal.Text = final.ToString();
}
}
but when i use backspace and delete number from any text box and write another number i receive wrong result , i think now it's clear i want when typing number in expenses.Text it add to buyTotal.Text and when i delete number when i typing it calculate the result
Please KeyUp instead of KeyDown, because your input value write in textbox after KeyDown event.
Please check this:
private void expenses_KeyUp(object sender, KeyEventArgs e)
{
if (expenses.Text != string.Empty)
{
decimal Pprice = Convert.ToDecimal(buyTotal.Text);
decimal expens = Convert.ToDecimal(expenses.Text);
decimal final = Pprice + expens;
buyTotal.Text = final.ToString();
}
if (e.KeyCode == Keys.Back)
{
buyTotal.Text = (from DataGridViewRow row in dataGridView1.Rows where row.Cells[6].FormattedValue.ToString() != string.Empty select Convert.ToDecimal(row.Cells[6].FormattedValue)).Sum().ToString();
}
}
Below code should be enough to calculate two numbers sum :
private void expenses_KeyDown(object sender, KeyEventArgs e)
{
try
{
if (expenses.Text != string.Empty)
{
double Pprice = Convert.ToDouble(buyTotal.Text);
double expens = Convert.ToDouble(expenses.Text);
double final = Pprice + expens;
buyTotal.Text = final.ToString("0.00");
}
else
{
buyTotal.Text="0.00";
}
}
catch(Exception exc)
{
buyTotal.Text="0.00";
}
}

Additional information: Input string was not in a correct format textbox c#

I have two textboxes in my form txtbox1 is for salary and txtbox2 is for result (txtbox1 / 30).
I chosed custom format for txtbox1 this is the code :
private void mtb_SJ02_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.Handled = !char.IsDigit(e.KeyChar) && e.KeyChar != (char)8 && e.KeyChar != ',') // 8 is back space
{
if (e.KeyChar == (char)13) // 13 is Enter
{
mtb_SJ02.Text = string.Format("{0:#,##0.00}", double.Parse(mtb_SJ02.Text));
}
}
}
The code work good as I want show me the number like this : 22.403,33
now i need to divide salary (txtbox1.text/30).
I create a string variable called sj :
string sj;
Now i want to calculate the result and show it in the txtbox2 with the same Format {0:#,##0.00}. This is the code:
void calculate ()
{
sj = ( Double.Parse(mtb_SALAIR02.Text ) / 30).ToString("{0:#,##0.00}");
mtb_SJ02.Text = sj;
}
when i run the code i get this message error :
enter image description here
so nay good idea how to do that plz ?
Try this:
if(textBox1.Text=="")
{
textBox1.Text="0";
}
textBox1.Text = string.Format("{0:#,##0.00}", double.Parse(textBox1.Text));
String sj = (Double.Parse(textBox1.Text, CultureInfo.CurrentCulture) / 30).ToString();
textBox2.Text = string.Format("{0:#,##0.00}", double.Parse(sj));
thanks for you all i think i fixed that by a friend
the solution is :
string sj;
void calculator ()
{
if (String.IsNullOrEmpty(mtb_SALAIR02.Text)) return;
mtb_SALAIR02.Text = string.Format("{0:#,##0.00}", double.Parse(mtb_SALAIR02.Text));
sj = (Double.Parse(mtb_SALAIR02.Text, CultureInfo.CurrentCulture) / 30).ToString();
mtb_SJ02.Text = string.Format("{0:#,##0.00}", double.Parse(sj));
}

Textbox KeyPress Event?

i have textbox only allow decimals and '+'
it allow only 1 Decimal "12.332" i need to allow 1 decimal before '+' and 1 decimal after '+' Example i have 12.43+12.23 i can't type the 12(.) because i allow only 1 decimal i am using Split method to get 2 parts before and after
and it is my code
// checks to make sure only 1 decimal is allowed
if (e.KeyChar == 46)
{
if ((sender as TextBox).Text.IndexOf(e.KeyChar) != -1)
e.Handled = true;
}
And this is My method
if(textBox1.Text.Contains('+')==true )
{
string Value = textBox1.Text;
string[] tmp = Value.Split('+');
string FirstValu = tmp[1];
string SecValu = tmp[0];
}
how to use method with event to allow another decimal place after '+'
I would say use two text boxes like someone said in the comments but if you want to be stubborn here is a function to run inside an event that is called when the text changes in the text box.
void textbox_textChanged(object sender, EventArgs e)
{
string text = textBox.Text;
int pointCounter = 0;
int addCounter =0
string temp = "";
string numbers = "0123456789";
for(int i =0;i<text.Length;i++)
{
bool found = false;
for(int j = 0;j<numbers.Length;j++)
{
if(text[i]==numbers[j])
{
temp+=text[i];
found = true;
break;
}
}
if(!found)
{
if('.' == text[i])
{
if(pointCounter<1)
{
pointCounter++;
temp+=text[i];
}
}else
if('+' == text[i])
{
if(addCounter<1)
{
pointCounter=0;
addCounter++;
temp+=text[i];
}
}
}
}
textBox.text = temp;
}
I would recommend using a Regex to validate your textbox. I would also suggest that using the textbox Validating event would be better than using the Leave event. Here is an example of using a regex in the Validating event:
private void textBox1_Validating(object sender, CancelEventArgs e)
{
TextBox tbox = (TextBox)sender;
string testPattern = #"^[+-]?[0-9]*\.?[0-9]+ *[+-]? *[0-9]*\.?[0-9]+$";
Regex regex = new Regex(testPattern);
bool isTextOk = regex.Match(tbox.Text).Success;
if (!isTextOk)
{
MessageBox.Show("Error, please check your input.");
e.Cancel = true;
}
}
You will find the Regex class in the System.Text.RegularExpressions namespace. Also make sure your textbox has the CausesValidation property set to true.
As an alternative you might also want to look at using the MaskedTextBox Class.

Categories