how to currency format under textbox? - c#

I want enter number in textbox, an my textbox convert automatically it in comma(,) format. I have tried to do this, but it works wrong. Help me? Like this 1,20(I JUST ENTER 120);
private bool IsNumeric(int Val)
{
return ((Val >= 48 && Val <= 57) || (Val == 8) || (Val == 46));
}
String str;
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
int KeyCode = e.KeyValue;
if (!IsNumeric(KeyCode))
{
if (KeyCode == 13)
{
e.Handled = true;
vendas();
str = null;
}
e.Handled = true;
return;
}
else
{
e.Handled = true;
}
if (((KeyCode == 8) || (KeyCode == 46)) && (str.Length > 0))
{
str = str.Substring(0, str.Length - 1);
}
else if (!((KeyCode == 8) || (KeyCode == 46)))
{
str = str + Convert.ToChar(KeyCode);
}
if (str.Length == 0)
{
textBox1.Text = "";
}
if (str.Length == 1)
{
textBox1.Text = "0,0" + str;
}
else if (str.Length == 2)
{
textBox1.Text = "0," + str;
}
else if ((str.Length > 2) && (str.Length != 6) && (str.Length != 9) && (str.Length != 12))
{
textBox1.Text = str.Substring(0, str.Length - 2) + "," + str.Substring(str.Length - 2);
textBox1.Text = textBox1.Text;
}
else if ((str.Length > 6) && (str.Length != 8) && (str.Length != 10) && (str.Length != 12))
{
textBox1.Text = str.Substring(0, str.Length - 3) + "," + str.Substring(str.Length - 1);
textBox1.Text = textBox1.Text;
}
}
It shows me 10,01 instead 0,01?

What you want is a MaskedTextBox.
Simply set of mask of "$999,999,990.00" and any input the user enters must be digits, and there must be at least 3, but the entry can be any number up to the hundreds of millions (if you need billions and trillions, just add more 9s and commas). As the user enters these digits, the formatting will adjust based on the mask. Here's the kicker; MaskedTextBox respects culture information, so if you specify the French culture, the commas become spaces, the decimal becomes a comma, and the dollar sign becomes the Euro symbol.

I was originally going to suggest MaskedTextBox, but MTB is designed for left-to-right style formatting of a fixed (or known in advanced, at least) length string, which makes it not so suitable for currency.
First, I'd recommend you avoid doing anything using keycodes or the like, and stick to something a bit more straightforward by just validating and editing the text when it changes:
void tb_TextChanged(object sender, EventArgs e)
{
//Remove previous formatting, or the decimal check will fail
string value = tb.Text.Replace(",", "").Replace("$", "");
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
tb.TextChanged -= tb_TextChanged;
//Format the text as currency
tb.Text = string.Format(CultureInfo.CreateSpecificCulture("en-US"), "{0:C2}", ul);
tb.TextChanged += tb_TextChanged;
}
}
The main part is string.Format(CultureInfo.CreateSpecificCulture("en-US"), "{0:C2}", ul); the en-US ensures it'll always show $ and decmials as '.'s. The {0:C2} formats the string as a number (0) of currency (:C) to 2 decimal spaces (2).
This doesn't prevent the user from entering text, but you can keep the previous text (eg '$23.00') and if the user enters something that isn't a number, decimal.TryParse will fail, at which point you can revert the text back to what it was before the user changed it (just by inserting an else block near the end of this event handler).
I'd recommend setting the TB text to '$0.00' or something initially, or the cursor will jump when it formats the first change. It also has some selection issues when commas are adding, which you could get around by storing the selection position just before formatting and changing it afterward, or doing something more complex, it's just an example.

Well, at first glance, I notice that nothing about your code whatsoever makes any sense.
First and foremost, learn coding standards for indentation. This code is extremely hard to read. I'm tempted to flag this question as offensive for having had to look at it.
Next, this line:
if (!IsNumeric(KeyCode){
Says: if the keycode is NOT numeric do the following stuff, where "the following stuff" is a whole bunch of numeric operations on a keycode which is presumed to be numeric.
Next, str is not defined anywhere in your method. Maybe it's defined globally, but that would just be silly. Rather, you should just get the current value of it programmatically.
And finally:
you don't need to reinvent the wheel. There are tons of tools out there that will do this kind of thing for you. In fact, I'm fairly sure win forms has a native control that'll do this. It might even be an attribute of textbox, I don't remember.

Related

Input only digits and control buttons

I want to input Salary with any value: 550,49, 2222,12, 9,3 and so on. But need to use control button like this: ,, backspace, ctrl + c, ctrl + v, ctrl + a.
Salary is TextBox with ShortcutsEnabled = true and event:
private void TbSalary_KeyPress(object sender, KeyPressEventArgs e)
{
char number = e.KeyChar;
if ((e.KeyChar <= 47 || e.KeyChar >= 58) && number != 8 && number != 44)
//digits, BackSpace and ,
{
e.Handled = true;
}
}
If remove this condition, the specified combinations will work. But not only numbers are entered.
Should I add tracking of all combinations here? Or is it possible to implement this task in another way?
MaskedTextBox requires a fixed number of characters with some "mask". But the Salary is different. Can be **,**, ******,* or *** and etc.
UPDATE
Prevent entering more than two numbers after the decimal point
if (number < ' ')
{
return;
}
if (number >= '0' && number <= '9')
{
if (this.Text.Contains(',')
&& this.SelectionLength == 0
&& this.SelectionStart > this.Text.IndexOf(',')
&& this.Text.Length - this.Text.IndexOf(',') > 2)
{
e.Handled = true;
}
return;
}
Please, don't use magic numbers like 47, let's work with characters. We should allow these characters:
'0'..'9' range (numbers)
control characters (which are below space ' ') for tab, backspace etc.
',' (comma) as a decimal separator
All the other characters should be banned.
Code:
private void TbSalary_KeyPress(object sender, KeyPressEventArgs e)
{
char number = e.KeyChar;
TextBox box = sender as TextBox;
if (number >= '0' && number <= '9' || number < ' ')
return; // numbers as well as backspaces, tabs: business as usual
else if (number == ',') {
// We don't want to allow several commas, right?
int p = box.Text.IndexOf(',');
// So if we have a comma already...
if (p >= 0) {
// ... we don't add another one
e.Handled = true;
// but place caret after the comma position
box.SelectionStart = p + 1;
box.SelectionLength = 0;
}
else if (box.SelectionStart == 0) {
// if we don't have comma and we try to add comma at the 1st position
e.Handled = true;
// let's add it as "0,"
box.Text = "0," + box.Text.Substring(box.SelectionLength);
box.SelectionStart = 2;
}
}
else
e.Handled = true; // all the other characters (like '+', 'p') are banned
}
Please, note, that there is possibility to Paste incorrect value (say, "bla-bla-bla") into TbSalary TextBox; to prevent it you can use TextChanged event:
private void TbSalary_TextChanged(object sender, EventArgs e) {
TextBox box = sender as TextBox;
StringBuilder sb = new StringBuilder();
bool hasComma = false;
foreach (var c in box.Text)
if (c >= '0' && c <= '9')
sb.Append(c);
else if (c == ',' && !hasComma) {
hasComma = true;
if (sb.Length <= 0) // we don't start from comma
sb.Append('0');
sb.Append(c);
}
string text = sb.ToString();
if (!text.Equals(box.Text))
box.Text = text;
}

Regex mask with replace for digits and only one hyphen C#

I saw a similar topic (this) but could not reach the ideal solution.
What I need:
A mask that works on the keypress event of aTextBox replacing non-numeric and excessive hyphens with "".
Allowing:
What is my difficulty?
Check for the entry of only one hyphen in the same expression.
I got into the solution using substring and it only worked in KeyUP, but I wanted to get through using an expression and keypress event.
What I've already tried:
using System.Text.RegularExpressions;
//trying to denie non-digit and hyphen.
//In conjunction with replace I remove everything that is not hyphen and digit
private static Regex MyMask = new Regex(#"[^\d-]");
private void inputSequential_KeyUp (object sender, KeyEventArgs e)
{
if (! String.IsNullOrEmpty (inputSequential.Text)
{
inputSequential.Text = MyMask.Replace (inputSequential.Text, "");
// MatchCollection matches = Regex.Matches (inputSequential.Text, "[\\ -]");
//
// if (matches.Count> 1)
// {
// for (int i = 1; i <= matches.Count - 1; i ++)
// {
// inputSequential.Text = inputSequential.Text.Substring (0, matches [i] .Index-1) + inputSequential.Text.Substring (matches [i] .Index, inputSequential.Text.Length);
// inputSequential.Text = inputSequential.Text.Replace (inputSequential.Text [matches [i] .Index] .ToString (), "");
//}
//}
}
}
Expected:
If you know better ways to do this please let me know.
Thanks for listening.
You can use a LINQ expression to get only the numbers and one hyphen:
string input = "12-3-47--Unwanted Text";
int hyphenCount = 0;
string output = new string(input.Where(ch => Char.IsNumber(ch) || (ch == '-' && hyphenCount++ < 1)).ToArray());
You seem at lost:
that expression: (:? ) - is not a nonmatched group. The correct variant is : (?: )
digitsOnly - it will be \d?
You should not escape -
If you are looking for a -, simply write it down.
For regex - Better write down in words, what are you looking for. For excluding or for taking in, does not matter, but SAY IN ENGLISH, what do you need.
Please, write down examples that should be accepted and these ones that should NOT be accepted.
For getting only numbers, possibly with - before, use:
-?\d+
tests
I searched here for some alternatives, with Regex or MaskedTextBox (This did not help me much because by default it is not supported in toolStrip where my textBox was).
At the end of the day the best solution I found was dealing with the input of values ​​to each char:
private void inputSequencial_KeyPress(object sender, KeyPressEventArgs e)
{
//Allow only digits(char 48 à 57), hyphen(char 45), backspace(char 8) and delete(char 127)
if ((e.KeyChar >= 48 && e.KeyChar <= 57) || e.KeyChar == 45 || e.KeyChar == 8 || e.KeyChar == 127)
{
switch (e.KeyChar)
{
case (char)45:
int count = inputSequencial.Text.Split('-').Length - 1;
//If the first char is a hyphen or
//a hyphen already exists I reject the entry
if (inputSequencial.Text.Length == 0 || count > 0)
{
e.Handled = true;
}
break;
}
}
else
{
e.Handled = true; //Reject other entries
}
}
private void inputSequencial_KeyUp(object sender, KeyEventArgs e)
{
//if last char is a hyphen i replace it.
if (inputSequencial.Text.Length > 1)
{
string lastChar = inputSequencial.Text.Substring(inputSequencial.Text.Length - 1, 1);
if (lastChar == "-")
{
inputSequencial.Text.Replace("-", "");
}
}
}
You can use this for nondigit [^\d]:
var st = "1kljkj--2323'sdfkjasdf2";
var result = Regex.Replace(st, #"^(\d).*?(-)[^\d]*(\d+)[^\d]*", #"$1$2$3");
1-23232

C# Masked TextBox with 0 or decimals

Users have a textbox where they have to either enter a 0 or a value from 0.0001 to 0.9999.
What regex can I use here? I have looked at other examples but don't see anything like this one.
I'd say this is quite an effective solution. It allows for any strings entered that is either just a '0' or strings with '0.' followed by up to 4 of any digit.
Regex myRegex = new Regex("^(?:(?:0)|(?:0.[0-9]{1,4}))$");
Console.WriteLine("Regex: " + myRegex + "\n\nEnter test input.");
while (true)
{
string input = Console.ReadLine();
if (myRegex.IsMatch(input))
{
Console.WriteLine(input + " is a match.");
}
else
{
Console.WriteLine(input + " isn't a match.");
}
}
Here's a list of tests...
Try this one:
/(0)+(.)+([0-9])/g
Also see thing link that might helps you build you won expreession.
http://regexr.com/
Try this, it will do the work but I was not tested for all cases.
Regex _regex = new Regex("^[0]+(.[0-9]{1,4})?$");
if (input == "0" || _regex.IsMatch(input))
{
//Match
}
else
{
//Does not match
}
Note: input is a string, in your case Textbox.Text!
This is ready to use KeyPress event handler of TextBox control. It will prevent any input, except numeric between 0.0001 and 0.9999:
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
//Only one dot is possible
if ((sender as TextBox).Text.Contains('.') && (e.KeyChar == '.')) e.Handled = true;
//Only numeric keys are acceptable
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar) && (e.KeyChar != '.')) e.Handled = true;
//Only one zero in front is acceptable, next has to be dot
if (((sender as TextBox).Text == "0") && (e.KeyChar == '0')) e.Handled = true;
double value = 0;
string inputValue = (sender as TextBox).Text + e.KeyChar;
if ((sender as TextBox).Text.Length > 0)
{
//Just in case parse input text into double
if (double.TryParse(inputValue, out value))
{
//Check if value is between 0.0001 and 0.9999
if (value > 0.9999) e.Handled = true;
if (((sender as TextBox).Text.Length > 4) && (value < 0.0001)) e.Handled = true;
}
}
else if (e.KeyChar != '0')
{
e.Handled = true;
}
}

How to insert hyphen "-" after 2 digits automatically in TextBox?

I have one TextBox for user to input number.
When user input to the TextBox then the format should be like this
01-22-34-40-33
I want to insert "-" after 2 digits in the TextChanged event handler.
I do something like this but no work:
if(txtRandomThirdTypeSales.Text.Length == 2)
{
txtRandomThirdTypeSales.Text += "-";
}
else if (txtRandomThirdTypeSales.Text.Length == 5)
{
txtRandomThirdTypeSales.Text += "-";
}
else if (txtRandomThirdTypeSales.Text.Length == 8)
{
txtRandomThirdTypeSales.Text += "-";
}
else if (txtRandomThirdTypeSales.Text.Length == 11)
{
txtRandomThirdTypeSales.Text += "-";
}
Can you please try this way,this may be will helpful for you.
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
string sVal = textBox1.Text;
if (!string.IsNullOrEmpty(sVal) && e.KeyCode != Keys.Back)
{
sVal = sVal.Replace("-", "");
string newst = Regex.Replace(sVal, ".{2}", "$0-");
textBox1.Text = newst;
textBox1.SelectionStart = textBox1.Text.Length;
}
}
Let me know if you need any help.
Maybe you can try this
if(txtRandomThirdTypeSales.Text.Count(x => x != '-') % 2 == 0)
{
txtRandomThirdTypeSales.Text += "-";
}
That way it counts all the chars that are not a - and checks if they are even. If they are, add the '-'.
You can make it more restrictive by checking that they are digits with a regex. ^\d
Can you please try this
if(txtRandomThirdTypeSales.Text.Length % 3 == 2)
{
txtRandomThirdTypeSales.Text += "-";
}
You can also add code to handle backspace key down and delete key down.
Have you tried TextBox masking? it is available in Winform controls
Here is your reference http://msdn.microsoft.com/en-us/library/system.windows.forms.maskedtextbox.aspx

Fire event on word wrap, multiline TextBox (Winforms)

So, I have written a method for limiting the number of lines allowed to write in a multiline textbox (since this is not a property provided by Microsoft). The method works in all cases, except when a wordwrap event occurs (when typing a single char, or when pasting text from clipboard). The code I hace right now:
protected void limitLineNumbers(object sender, KeyPressEventArgs e, UInt16 numberOfLines)
{
int[] specialChars = { 1, 3, 8, 22, 24, 26 }; // ctrl+a, ctrl+c, backspace, ctrl+v, ctrl+x, ctrl+z
bool found = false;
string lastPressedChar = "";
TextBox temp = (TextBox)sender;
foreach (int i in specialChars)
{
if (i == (int)e.KeyChar)
found = true;
}
if (!found)
lastPressedChar = e.KeyChar.ToString(); // Only add if there is a "real" char
int currentLine = temp.GetLineFromCharIndex(temp.SelectionStart) + 1;
int totalNumberOfLines = temp.GetLineFromCharIndex(temp.TextLength) + 1;
if ((int)e.KeyChar == 1)
temp.SelectAll();
// Paste text from clipboard (ctrl+v)
else if ((int)e.KeyChar == 22)
{
string clipboardData = Clipboard.GetText();
int lineCountCopiedText = 0;
foreach (char c in clipboardData)
{
if (c.Equals("\n"))
++lineCountCopiedText;
}
if ((currentLine > numberOfLines || (totalNumberOfLines + lineCountCopiedText) > numberOfLines))
e.Handled = true;
}
// Carrige return (enter)
else if ((int)e.KeyChar == 13)
{
if ((currentLine + 1) > numberOfLines || (totalNumberOfLines + 1) > numberOfLines)
e.Handled = true;
}
// Disallow
else if ((currentLine > numberOfLines) || (totalNumberOfLines > numberOfLines))
e.Handled = true;
}
So, do you guys have some ideas how I can make this method more complete? The best solution would be to catch the wordwrap event, but as far as I can understand, this can't be done? The other solution would be to delete the line(s) of text, if it exceeds the maximum allowed.
Or is it possible a better solution than the one I came up with? Appreciate your input.

Categories