可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have a problem that is haunting me for a while. I tried some solutions but they didn't worked.
I have a textbox that is for cash input ($999,99 for example). However I need to automatically input the "," and "." to display the value correctly.
I tried two solutions. One of them is this:
private void tx_ValorUnidade_TextChanged(object sender, EventArgs e)
{
string value = tx_ValorUnidade.Text.Replace(",", "").Replace("R$", "");
decimal ul;
//Check we are indeed handling a number
if (decimal.TryParse(value, out ul))
{
//Unsub the event so we don't enter a loop
tx_ValorUnidade.TextChanged -= tx_ValorUnidade_TextChanged;
//Format the text as currency
tx_ValorUnidade.Text = string.Format(System.Globalization.CultureInfo.CreateSpecificCulture("pt-BR"), "{0:C2}", ul);
tx_ValorUnidade.TextChanged += tx_ValorUnidade_TextChanged;
}
}
The result, however, is very weird.
The other one is this:
private void tx_ValorUnidade_KeyUp(object sender, KeyEventArgs e)
{
if (!string.IsNullOrEmpty(tx_ValorUnidade.Text))
{
System.Globalization.CultureInfo culture = new System.Globalization.CultureInfo("en-US");
int valueBefore = Int32.Parse(tx_ValorUnidade.Text, System.Globalization.NumberStyles.AllowThousands);
tx_ValorUnidade.Text = String.Format(culture, "{0:N0}", valueBefore);
tx_ValorUnidade.Select(tx_ValorUnidade.Text.Length, 0); *
}
}
This one kinda works, but there is a issue: if the user wants to insert somethink like $10,00 it can't. It also crashes after 5 numbers.
For original reference, I got the 2 codes from other questions here.
How can I fix it? Am I using the examples wrong? Any thought is welcome.
回答1:
I think you will be better off when formatting when the user moves to the next control, e.g. like below. Otherwise it will be very confusing as the text will change itself as the user is typing:
private void textBox1_Leave(object sender, EventArgs e)
{
Double value;
if (Double.TryParse(textBox1.Text, out value))
textBox1.Text = String.Format(System.Globalization.CultureInfo.CurrentCulture, "{0:C2}", value);
else
textBox1.Text = String.Empty;
}
回答2:
Some people might want to actually format a textbox as they type. So this is my solution if anyone is looking for one.
It actually assumes you are entering one digit at a time so therefore as you press "1" it assumes "$0.01" and when they press "2" it then assumes "$0.12" and so on and so forth.
I could not find anything online about formatting as they typed. It has been tested and if any errors let me know.
private void textBox1_TextChanged(object sender, EventArgs e)
{
//Remove previous formatting, or the decimal check will fail including leading zeros
string value = textBox1.Text.Replace(",", "")
.Replace("$", "").Replace(".", "").TrimStart('0');
decimal ul;
//Check we are indeed handling a number
if (decimal.TryParse(value, out ul))
{
ul /= 100;
//Unsub the event so we don't enter a loop
textBox1.TextChanged -= textBox1_TextChanged;
//Format the text as currency
textBox1.Text = string.Format(CultureInfo.CreateSpecificCulture("en-US"), "{0:C2}", ul);
textBox1.TextChanged += textBox1_TextChanged;
textBox1.Select(textBox1.Text.Length, 0);
}
bool goodToGo = TextisValid(textBox1.Text);
enterButton.Enabled = goodToGo;
if (!goodToGo)
{
textBox1.Text = "$0.00";
textBox1.Select(textBox1.Text.Length, 0);
}
}
private bool TextisValid(string text)
{
Regex money = new Regex(@"^\$(\d{1,3}(\,\d{3})*|(\d+))(\.\d{2})?$");
return money.IsMatch(text);
}
To make it look nice I'd recommend starting the text box with the text $0.00 on the form load like so:
private void Form1_Load(object sender, EventArgs e)
{
textBox1.Text = "$0.00";
textBox1.SelectionStart = inputBox.Text.Length;
}
回答3:
Just a slight modification to GreatNates answer.
private bool KeyEnteredIsValid(string key)
{
Regex regex;
regex = new Regex("[^0-9]+$"); //regex that matches disallowed text
return regex.IsMatch(key);
}
and insert this method into the textboxs preview input event like this.
private void TextBox1_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
e.Handled = KeyEnteredIsValid(e.Text);
}
That way you make sure that you can't make any mistakes when typing anything. You are limited to numbers only with my methods, while nates methods are formatting your string.
Cheers.
回答4:
We can try following one as well.
txtCost.Text = String.Format("{0:c2}", myObj.Cost);
回答5:
I struggled with this for hours too. I tried to use maskedTextBox but that was just clunky for the users to enter text. I also didn't like having to deal with the masking for calculations. I also looked into using the databinding formatting but that just seemed overkill.
The way I ended up going was not to use a TextBox for inputting numbers. Use the NumericUpDown object instead. No need conversion and you can set your decimals and thousands commas in the properties if you like ;) I set my increment to 1000 since i was dealing with income.
Do be aware that the .Text that comes through will have commas when there is a penny decimal and amount over 1000 (i.e. 1,000.01) , otherwise the decimal and trailing 0s are dropped.
I also found this short and sweet solution which worked well but was unneccesary with numericUpDown. You can put this on leave event.
Decimal val;
if (Decimal.TryParse(TxtCosPrice.Text, out val))
TxtCosPrice.Text = val.ToString("C");
else
MessageBox.Show("Oops! Bad input!");
回答6:
This is my solution, it puts only dots, not money symbol. Hope can help somenone.
private void textBox1_KeyUp(object sender, KeyEventArgs e)
{
e.SuppressKeyPress = TextBox2Currency((TextBox)sender, e.KeyValue);
}
private bool TextBox2Currency(TextBox sender,int keyval)
{
if ((keyval >= 48 && keyval <= 58) || keyval == 46 || keyval == 8)
{
int pos = sender.SelectionStart;
int oriLen = sender.Text.Length;
string currTx = sender.Text.Replace(".", "").ToCurrency();
int modLen = currTx.Length;
if (modLen != oriLen)
pos += (modLen - oriLen);
sender.Text = currTx;
if ( pos>=0)
sender.SelectionStart = pos;
return false;
}
return true;
}