c# How to validate when pasting into textbox - c#

I have written a little program. It works almost as I want, I just have one problem. I am trying to copy all functions I have found in the other program.
I have a TextBox, when the user can write a phone number. Firstly, he is only allowed to use digits and "+"and "-", so I use:
private void textBoxPhoneNumber_KeyPress(object sender, KeyPressEventArgs e)
{
if ((char.IsDigit(e.KeyChar) == false) && (e.KeyChar != '+') && (e.KeyChar != '-') && (e.KeyChar != '\b')) e.Handled = true;
}
Then I want the phone number to be in certain format (+12-34-1234567), so I use:
private bool IsPhoneNumberCorrect(string name)
{
return Regex.IsMatch(name, #"^+\+[0-9]{2}-[0-9]{2}-[0-9]{7}$", RegexOptions.None);
}
and finally this (with TextChange):
private void phoneNumberValidity(object sender, EventArgs e)
{
counter4 = Convert.ToInt32(IsPhoneNumberCorrect(textBoxPhoneNumber.Text));
pictureBoxPhoneNumber.Image = imageList1.Images[counter4];
checkIfOk();
textBoxPhoneNumber.Focus();
}
I use counter4 as a part of method (checkIfOk) that enables button. There is also an "X" icon that changes into "tick" when the number is given in proper format.
It works perfectly for me (just like in the program I am copying) - when the user writes something in the TextBox, he can only use digits and "+" and "-" and when the format is ok the icon changes and when other textboxes are also ok, the Ok buton enables.
Now, finally, the problem:
I am able to paste something from the Clipboard. In the original program, when I paste something with letters, digits and other signs, only digits and "+" and "-" remains. My program accepts everything in such situation.
I've been looking for something that might be helpful, but all I have found was very complicated. Is there a way to do it?
I tried to do something like this. It causes that when pasting only digits and "+" and "-" remains as it should, but the user can't write anything.
I am still a beginner. Maybe I am making a simple mistake?
private void phoneNumberValidity(object sender, EventArgs e)
{
Regex regex = new Regex("[^0-9-+]");
if (regex.IsMatch(Clipboard.GetText()))
{
counter4 = Convert.ToInt32(IsPhoneNumberCorrect(textBoxPhoneNumber.Text));
pictureBoxPhoneNumber.Image = imageList1.Images[counter4];
string output = regex.Replace(Clipboard.GetText(), "");
textBoxPhoneNumber.Text = output;
checkIfOk();
textBoxPhoneNumber.Focus();
}
}
I am trying to do something like this:
private void phoneNumberValidity(object sender, EventArgs e)
{
counter4 = Convert.ToInt32(IsPhoneNumberCorrect(textBoxPhoneNumber.Text));
pictureBoxPhoneNumber.Image = imageList1.Images[counter4];
checkIfOk();
textBoxPhoneNumber.Focus();
Regex regex = new Regex("[^0-9-+]");
if (textBoxPhoneNumber.Text.Contains("a"))
{
if (regex.IsMatch(Clipboard.GetText()))
{
string output = regex.Replace(Clipboard.GetText(), "");
textBoxPhoneNumber.Text = output;
}
}
}
I know that it's not exactly what I want, but maybe someone can give some clues...
Generally i thought, that I'd like to check if the text in tb contains some unwanted elements, but I don't know how to check it. As you can see, it checks only one unwanted element.

First of all, please use TRY-Catch for the Convert.ToInt32 !
Second: Use TextChanged event, and validate the input with the actual content of the TextBox
To validate, you can do something similar:
string output = ""
string clipboardText = GetClipboardText()
for each chara in clipboardText's characters
if chara.isNumeric or chara=='+' or chara == '-'
output += chara
end foreach
Of course its just a simple soultion, but you can confgure it as you want.
Or if you want more complex way, you can play with the regex... Start with number or + - BUT not contains alphabetical char. Based on your request.

This is what I made, and it works :) I will only add try-catch block as Krekkon has suggested.
private void phoneNumberValidity(object sender, EventArgs e)
{
counter4 = Convert.ToInt32(IsPhoneNumberCorrect(textBoxPhoneNumber.Text));
pictureBoxPhoneNumber.Image = imageList1.Images[counter4];
if (Regex.IsMatch(textBoxPhoneNumber.Text, "[^0-9-+]"))
{
Regex regex = new Regex("[^0-9-+]");
string output = regex.Replace(Clipboard.GetText(), "");
textBoxPhoneNumber.Text = output;
}
checkIfOk();
textBoxPhoneNumber.Focus();
}
Maybe it will help someone in the future.

Maybe you should try like this: leave the first version of phoneNumberValidity method as it is and then check if the tb Text has some unwanted elements, get rid of them.

Related

How to compare KeyEventArgs to a character?

I have a TextEdit.PreviewKeyDown method where I want to check if an input character is equal to a special character of my choosing.
For an instance I want to check if the user's input character is '#'. I'd use:
if(e.Key == Key.D3 && (Keyboard.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift)
The problem is I don't know what the special character will be at the time and I can't possibly program all the cases, so I wanted something like:
string strSpecChar = GetSpecialCharacter();
if(strSpecChar = e.Key) {do_sth();}
Which doesn't work at all, because if I press, for example '3', the e.Key value will be equal to 'D3', so if my strSpecChar value is '3' I can't get to the do_sth()
I have browsed through the System.Windows.Input.KeyEventArgs docs and I've found nothing and I've also read some discouraging posts on other forums.
Is there any way I would be able to compare the PreviewKeyDown e and string strSpecChar?
private void Window_PreviewKeyDown(object sender, KeyEventArgs e)
{
string strNewLigneSign = String.Empty;
if (InsertTextDialogHelper != null)
strNewLigneSign = InsertTextDialogHelper.GetNewLineSign();
if (e.Key.Equals(strNewLigneSign))
{
if (!String.IsNullOrEmpty(strNewLigneSign))
{
int strCaretPosition = TextBox.CaretIndex;
e.Handled = true;
string strNewText = "\r\n";
CurrentDialogData.TextValue = CurrentDialogData.TextValue.Insert(strCaretPosition, strNewText);
TextBox.CaretIndex = strCaretPosition + strNewText.Length;
}
}
}
EDIT:
As per #mm8's suggestion I tried to implement it in the TextEdit.PreviewTextInput property as follows:
XAML
<dxe:TextEdit Name="TextBox"
PreviewTextInput="TextBox_PreviewTextInput" \">
</dxe:TextEdit>
C#
private void TextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
string strNewLigneSign = String.Empty;
if(InsertTextDialogHelper != null)
strNewLigneSign = InsertTextDialogHelper.GetNewLineSign();
if(!String.IsNullOrEmpty(strNewLigneSign))
{
if(e.Text.Contains(strNewLigneSign))
{
int strCaretPosition = TextBox.CaretIndex;
e.Handled = true;
string strNewText = Unhashify(e.Text);
CurrentDialogData.TextValue = CurrentDialogData.TextValue.Insert(strCaretPosition, strNewText);
TextBox.CaretIndex = strCaretPosition + strNewText.Length;
}
}
}
However when I run the app and set the breakpoints anywhere inside that method it seems never to go inside it.
The exact same solution worked for me back when I used it in wpf's TextBox, but as soon as I switched to devexpress, the TextBox_PreviewTextInput method is never called.
A key is a key and not a character. It's eventually mapped to a character depending on the input device.
You may want to consider handling PreviewTextInput and check the value of Text[0] of the TextCompositionEventArgs instead of handling PreviewKeyDown.

Allow only 1 symbol in TextBox

I am currently working on a custom control that allow users to enter either a decimal or in time format (hh:mm). So I would like that if the TextBox contain a period(.), the user will no longer add/enter a colon(:) and vice versa.
I have this code below so that user can only enter numeric, a period and a colon.
private void txtTime_KeyPress(object sender, KeyPressEventArgs e)
{
if ((!char.IsControl(e.KeyChar) & !char.IsDigit(e.KeyChar) & !(Convert.ToString(e.KeyChar) == ".") & !(Convert.ToString(e.KeyChar) == ":")))
{
e.Handled = true;
}
else
{
//only allow one '.' & ':'
if (e.KeyChar == '.' && (sender as TextBox).Text.IndexOf('.') > -1)
{
e.Handled = true;
}
else if (e.KeyChar == ':' && (sender as TextBox).Text.IndexOf(':') > -1)
{
e.Handled = true;
}
}
}
So my question is, how will I do it?
Can somebody help me? Thanks in advance.
For operators it is a nuisance if they have typed something, and they want to correct it, but they can't because there is an incorrect dot or a semicolon in it.
Suppose the operator tried to type 14:38:21, but instead types:
14.38
"Oh no, this is wrong, I wanted 14.38:21! So let's first continue typing :21 and then go back to change the dot into a colon!"
Imagine the operator's frustration when he can't type :21, and doesn't understand why
In windows forms, only validate entered input when the operator expresses he finished editing the input.
Therefore, use TextBox.OnValidating. When this one is called, you can either accept or decline the input and tell the operator what is wrong.
protected override void OnValidating (CancelEventArgs e)
{
e.Cancel = this.IsInputErrorDetected;
if (e.Cancel)
{
this.DisplayInputProblem();
}
}
Bonus point: also works with copy-paste.
I am not sure, if I understand your question good.
Maybe you are looking for maskedTextBox where you can specify mask of user input.
This one has mask for short time HH:MM

Comparing textbox.Text with a variable

I'm comparing textBox2.text to a variable called 'word', word contains a random word coming from a txt file. The user needs to guess the word by placing the word in the textBox2 and if the user is correct a messageBox comes up to show he won.
the code I wrote doesn't show any errors and seems good to me, maybe theirs some other way to do this application.
string word; // variable for random word generated
word = RandomWord(); // Calling random word generator method
private void button2_Click(object sender, EventArgs e)
{
if (textBox2.Text == word)
{
label4.Text = "You Won";
MessageBox.Show("You Guessed The Word = " + (word), "You won");
}
else
{
DoesNotMatch();
}
}
First, fix your formatting like I did in this answer. Then, there are some things to remember about strings:
They are a nullable type.
Even one character being of a different case breaks equality.
Any whitespace, including trailing spaces/padding, can break equality.
string word; // variable for random word generated word = RandomWord();
// Calling random word generator method
private void button2_Click(object sender, EventArgs e) {
if(textBox2.Text != null && textBox2.Text.Trim() != string.Empty)
{
if (textBox2.Text.Trim().ToLower() == word.Trim().ToLower())
{
label4.Text = "You Won";
MessageBox.Show("You Guessed The Word = " + (word), "You won");
}
else
{
DoesNotMatch();
}
} else { throw new ApplicationException("Invalid entry, please try again.");}
}
With those concerns in mind, I applied string.Trim() and .Lower() to ensure any whitespace is cleaned up and case is ignored. Before I even get that far, I confirm that text is actually present in the .Text property of the control. If it isn't, we throw an exception (although you may just want to pop a MessageBox). There are cleaner ways to do this and account for various cultural differences, but this is the quick, dirty way you'd normally see in an office environment.

How do I make one word in a text box end a program?

So one of the forms I have to create is where you enter a first and last name and then it splits the two names and puts them next to the appropriate labels, form design: https://gyazo.com/9b34dca0c1cd464fd865830390fcb743 but when the word stop is entered in any way e.g. Stop, StOp, sToP etc. it needs to end.
private void btnSeparate_Click(object sender, EventArgs e)
{
string strfullname, strgivenname, strfamilyname, strfirstname;
int int_space_location_one, int_space_location_two;
strfullname = txtFullName.Text;
int_space_location_one = strfullname.IndexOf(" ");
strgivenname = strfullname.Substring(0, int_space_location_one);
lblGivenEntered.Text = strgivenname;
strfirstname = strfullname.Remove(0, int_space_location_one + 1);
int_space_location_two = strfirstname.IndexOf(" ");
strfamilyname = strfirstname.Substring(int_space_location_two + 1);
lblFamilyEntered.Text = strfamilyname;
}
This is my current code, I have tried many different ways to get the word stop to end it but it wont work so that's why there is currently no code trying to stop the program, the main problem I get is because it is searching for a space between the first and last name and it obviously doesn't have one for one word it just crashes.
Any help with this would be amazing, thanks in advance.
Just hook up the TextChanged event and go like this:
private void TextChanged(Object sender, EventArgs e)
{
// If text, converted to lower-characters contains "stop" -> Exit
if(txtFullName.Text.ToLower().Contains("stop"))
{
// What I understand as "stopping it".
Application.Exit();
}
}
IF with "stop it" you mean to cancle the operation:
private void btnSeparate_Click(object sender, EventArgs e)
{
// If text, converted to lower-characters contains "stop" -> Exit
if (txtFullName.Text.ToLower().Contains("stop"))
{
// What I understand as "stopping it".
Application.Exit();
}
else
{
// Your code inside the else block
}
}
Short version of everything: Also covering no spaces problem
private void btnSeparate_Click(object sender, EventArgs e)
{
// Save how many words are inside
int wordsInText = txtFullName.Text.Split(' ').Length;
// Save if "stop" was typed into the textbox
bool stopExisting = !txtFullName.Text.ToLower().Contains("stop");
// If text has exactly 3 words and "stop" is NOT existing
if (wordsInText == 3 && !stopExisting)
{
// Save array of splitted parts
string[] nameParts = txtFullName.Text.Split(' ');
// This is never used??
string strfirstname = nameParts[1];
// Set name-parts to labels
lblGivenEntered.Text = nameParts[0];
lblFamilyEntered.Text = nameParts[2];
}
// If text has NOT exactly 3 words and "stop" is NOT existing
else if(wordsInText != 3 && !stopExisting)
{
// If there are no 3 words, handle it here - MessageBox?
}
// If "stop" IS existing
else if(stopExisting)
{
// If text contains "stop" handle it here
// Application.Exit(); <-- if you really want to exit
}
}
You could just check, if one of the entered words is equal to the word "stop". There you need a StringComparions which ignores the case. Or you could parse the entered word into lower/upper-cases.
So if the check is true, you could just end the program with
Environment.Exit(0);
You could just check, if one of the entered words is equal to the word "stop". There you need a StringComparions which ignores the case. Or you could parse the entered word into lower/upper-cases.
So if the check is true, you could just end the program with
Environment.Exit(0);
Code:
if (strfullname.ToLowerInvariant().Contains("stop"))
{
Environment.Exit(0);
}

Accelerate add text to a TextBox

I have code to set text of TexBox as
textBox1.Text = s;
where s is a string that have more than 100,000 char, and it take long time to show text on textBox.
Anybody have solution to make it faster ?
To do that split the s string into many strings, and use the AppendText to add those subStrings, if you check MSDN you will see that :
The AppendText method enables the user to append text to the contents of a text control without using text concatenation, which, can yield better performance when many concatenations are required.
public string s = "Put you terribly long string here";
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//For responsiveness
textBox1.BeginInvoke(new Action(() =>
{
//Here's your logic
for (int i = 0; i < s.Length; i += 1000)
{
//This if is just for security
if (i+1000 > s.Length)
{
//Here's your AppendText
textBox1.AppendText(s.Substring(i, s.Length-i));
}
else
{
//And it's here as well
textBox1.AppendText(s.Substring(i, 1000));
}
}
}));
}
I used the value 1000, you can use 1500 , 2000 , choose the one that gives better result.
Hope this helps.
Update :
AppendText is available for both WindowsForms and WPF, too bad can't find it on WindowsPhone and WinRT. so I think this solution may help you a lot
break s in sub strings and when you pass first sub string to the text box it will appear after that it concatenate to the second and so on.
other way is that use loop to set the value
for(int i=0;i<s.length; i++)
{
textBox1.Text += s[i];
}
may these helps you

Categories

Resources