Filtering WinForms Textbox inputs - c#

So, I have a textbox in my WinForms program, and I want the textbox to only allow answers with at least two dots, and starting with letter "N" or "M".
private void SaveText_Click(object sender, EventArgs e)
{
MainNotifs.Show(this, "Attached !");
attachment = true;
}
I want it to set value of "attachment" to true, only if value of the textbox passes the criteria above.

string input = txtBox.Text;
if((input.StartsWith("N") || input.StartsWith("M")) && input.Count(c => c == '.') >= 2)
{
attachment = true;
}

Related

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.)

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.

Restrict input to textbox only "I-10" or "IV-12" or "III-7"

So, I have a homework and I need help. I must restrict my textbox input to class number. Our classes are in format: "I-1", "II-1", "III-1", "IV-1", "I-10", "IV-10" and so on. So my code is:
private void tbRazred_KeyPress(object sender, KeyPressEventArgs e)
{ //ogranicenje textbox-a da moze da upisuje razred u formatu npr. IV-1
duzina = tbRazred.TextLength;
if (brprivremeni < duzina)
{
brprivremeni = duzina;
if (e.KeyChar.ToString() != "-")
switch (brslova)
{
case 1:
{
e.Handled = e.KeyChar != 'I'; brslova++;
break;
}
case 2:
{
e.Handled = e.KeyChar != 'I' && e.KeyChar != 'V'; brslova++;
break;
}
case 3:
{
if (tbRazred.Text == "IV") e.Handled = e.KeyChar != '-'; brslova++;
break;
}
case 4:
{
if (tbRazred.Text == "III") e.Handled = e.KeyChar != '-'; brslova++;
break;
}
}
else e.Handled = !char.IsDigit(e.KeyChar);
}
}
duzina gets the textbox length
btprivremeni is temporary value which gets the textbox length and its compared to the new textbox length, so if its same or lower it doesn't do anything. Please help me, I'm doing this for a couple days and now I must ask you.
There's a few different ways to do this. Since your list potential options is pretty small, I would put all of the "Class Numbers" into a list of strings. I would then check the textbox's text against that list with an Event Handler from some other control.
Textbox tbRazred = new Textbox();
List<string> classNumbers = new List<string>();
// Add all your items, here is one of them
classNumbers.Add("I-1");
// Call the following based on some checker routine or Control. Maybe when the Textbox loses focus?
bool pass = false;
foreach (string thisClass in classNumbers)
{
if (thisClass == tbRazred.Text)
{
pass = true;
}
}

Categories