C# Search for first number in integer/string - c#

I have a textbox where people have to enter a number but I don't want to them to type the number 0 in first, how do I do this?
Example: If they type, 10 it's ok but if they type 010 it's not ok and I want a window to appear and tell them to try again.
Thanks!

Add TextChanged handler to your textbox (in your form find event for TextBox and type this name: TextBox_TextChanged):
void TextBox_TextChanged(object sender, EventArgs e)
{
var textBox = sender as TextBox;
if (textBox != null)
{
textBox.Text = textBox.Text.Trim();
if (textBox.Text.Length > 0 && textBox.Text[0] == '0')
{
textBox.Text = textBox.Text.TrimStart('0');
MessageBox.Show("Incorrect value");
}
}
}
Or in code:
TextBox textBox = new TextBox();
textBox.TextChanged += TextBox_TextChanged;

Use the TextChanged event. (Double click on the event in the properties of the textbox in the designer) In this example trim any leading spaces before comparison and remove the character if it is a 0
private void textBox1_TextChanged(object sender, EventArgs e)
{
string input = textBox1.Text.TrimStart(' ');
if (input.Length == 1)
{
textBox1.Text = input == "0" ? "" : input;
}
}
EDIT
As pointed out by m.rogalski and Roma the version above allows for entering the 0 after the input of a valid character. This version bellow will correct this mistake:
private void textBox1_TextChanged(object sender, EventArgs e)
{
textBox1.Text = textBox1.Text.TrimStart('0');
}

This should work:
private void MyTextBox_TextChanged(object sender, EventArgs e)
{
var textBox = sender as TextBox;
if (textBox.Text.StartsWith("0"))
//alert user
MessageBox.Show("Invalid starting character");
}
Of course you need to bind TextChanged event in designer or in code like this:
MyTextBox.TextChanged += MyTextBox_TextChanged;

Starting from the beginnign :
If they type, 10 it's ok but if they type 010 it's not ok
If it's okay for user to type integer ranging from 0 to infinity then you can use this :
if(textBox.Text.Length > 1 && textBox.Text[0] == '0')
This assumes that user can type '0' as a first sign only if it is only sign. If that's not what you wanted then change it to this :
if(textBox.Text.Length > 0 && textBox.Text[0] == '0')
Going further :
I want a window to appear and tell them to try again
You can just show MessageBox and clear text inside textBox :
textBox.Text = string.Empty;
MessageBox.Show("Value entered is incorrect. Please try again");
Then combining these you'll have something like :
if(textBox.Text.Length > 1/* or 0 depending on what you need */ && textBox.Text[0] == '0')
{
textBox.Text = string.Empty;
MessageBox.Show("Value entered is incorrect. Please try again");
}

put this code to after Initialize method
textBox1.TextChanged = (s, o) =>
{
if (textBox1.Text.StartsWith("0"))
{
textBox1.Text = textBox1.Text.Remove(0, 1);
MessageBox.Show("Cant start with '0'");
}
};

Perhaps you could have a ViewModel representing some textboxes, one of which is your "Number" textbox. Then you can use an attribute on your Number property to make sure it is validated.
public class MyViewModel
{
...
[Required]
[NumberValidation]
string NumberTextBox {get;set;}
where NumberValidation is another public class implementing a ValidationAttribute
[AttributeUsage(AttributeTargets.Property]
public class NumberValidation : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (value.StartsWith("0"))
{
return new ValidationResult(ErrorMessage, "Please enter another number!");
}
return ValidationResult.Success;
}
}

Related

How depending the selected value of a combobox, i can allow in a numericupdown the value to be >= 0?

Example
I have a combobox with a list of 3: entry, exit and transfer and a numericupdown called: txtTotal that starts in 0
when i select entry or exit should show error missing total but if a select transfer should allow you to continue even if its 0 or another number
If you want to show error missing total when you select entry or exit and allow you to continue even if txttotal shows 0 or another number when you select transfer, you could refer to the following code:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
comboBox1.Items.Add("Entry");
comboBox1.Items.Add("Exit");
comboBox1.Items.Add("Transfer");
}
private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
if (comboBox1.Text == "Entry" || comboBox1.Text == "Exit")
{
MessageBox.Show("Error missing total is " + txtTotal.Text);
}
if (comboBox1.Text == "Transfer")
{
// You should replace this code with what you want to do
string FileToRead = "the path of txt file";
string[] lines = File.ReadAllLines(FileToRead);
foreach (string str in lines)
{
if (str == "2")
{
txtTotal.UpButton();
}
}
}
}
}

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));
}

MaskedTextBox Currency Input Mask Limits

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);
}

How to make winforms textbox autocomplete correct capitalisation?

Using a winforms textbox with autocomplete set to SuggestAppend I can type out part of a string and the rest will be suggested to me fine.
If a user types "smi" looking for "Smith, John" and then autocompletes the rest of the string by tabbing then the textbox contains "smith, John". But, if the user clicks on the name then the capitalisation is correct.
Is there a way I can get the autocomplete to re-capitalise the user inputted part of the string when the suggestion is accepted by tabbing?
Pressing tab leads to:
Clicking name leads to (this is what I want):
To handle this situation I handled the textbox Leave event. The idea is to split the text by comma, uppercase the first letter of the resulting strings, then join the strings back together.
private void textBox1_Leave(object sender, EventArgs e)
{
string[] strings = this.textBox1.Text.Split(new char[] { ',' });
for (int i = 0; i < strings.Length; i++)
{
strings[i] = string.Format("{0}{1}", char.ToUpper(strings[i][0]), strings[i].Substring(1));
}
this.textBox1.Text = string.Join(",", strings);
}
Here's the function I came up with the end, it replaces the textbox's content with a line from the AutoCompleteCustomSource of the textbox (sorted alphabetically).
So, this will still work for any case (e.g if user entered "aLLeN" it would still correct to "Allen,Charlie (ID:104)"
private void fixContent()
{
String text = txtAutoComplete.Text;
List<String> matchedResults = new List<String>();
//Iterate through textbox autocompletecustomsource
foreach (String ACLine in txtAutoComplete.AutoCompleteCustomSource)
{
//Check ACLine length is longer than text length or substring will raise exception
if (ACLine.Length >= text.Length)
{
//If the part of the ACLine with the same length as text is the same as text, it's a possible match
if (ACLine.Substring(0, text.Length).ToLower() == text.ToLower())
matchedResults.Add(ACLine);
}
}
//Sort results and set text to first result
matchedResults.Sort();
txtAutoComplete.Text = matchedResults[0]
}
Thanks to OhBeWise I attached this to the textbox leave event:
private void txtAutoComplete_Leave(object sender, EventArgs e)
{
fixContent();
}
But also I needed to cover situations when the autocomplete has been accepted which occur when enter, tab, left and right are pressed. Attaching this to the keydown event doesn't work because I think the autocomplete captures the event beforehand, so I attached to the previewkeydown event:
private void txtAutoComplete_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
Keys key = (Keys)e.KeyCode;
if (key == Keys.Enter || key == Keys.Tab || key == Keys.Left || key == Keys.Right)
{
fixContent();
}
}
simple ;
private void textbox_TextChanged(object sender, EventArgs e)
{
AutoCompleteStringCollection a = new AutoCompleteStringCollection();
a = textbox.AutoCompleteCustomSource;
for (int i = 0; i < a.Count; i++)
{
if (a[i].ToLower() == textbox.Text.ToLower())
{
textbox.Text= a[i].ToString();
break;
}
}
}

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