I Tried Some Codes But Didnt Work
For Example
I Found This And It Didnt Work:
if (!char.IsControl(e.KeyChar)
&& !char.IsDigit(e.KeyChar)
&& e.KeyChar != '.')
{
e.Handled = true;
}
// only allow one decimal point
if (e.KeyChar == '.'
&& (sender as TextBox).Text.IndexOf('.') > -1)
{
e.Handled = true;
}
You have a very simple, yet understandable error there.
The Handled property of KeyPressEventArgs should be set to true to keep the operating system from further processing the key.
https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.keypresseventargs?view=netframework-4.8
In other words, set this to true when you want to PREVENT the key.
Therefore, change your code like this to ALLOW further processing when the pressed key fits the conditions.
Please also see how the boolean variables are introduced to make the code readable.
The code below allows
A ( - ) character if it is the first char in the text box
A ( . ) character if it is not the first char and if there are no other dots
Any control characters
And any digits.
Good luck.
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
bool isControl = char.IsControl(e.KeyChar);
bool isDigit = char.IsDigit(e.KeyChar);
bool isDot = e.KeyChar == '.';
bool alreadyHasADot = (sender as TextBox).Text.IndexOf('.') != -1;
bool isHyphen = e.KeyChar == '-';
bool isFirstChar = (sender as TextBox).Text.Length == 0;
bool isAllowed =
isControl ||
isDigit ||
(isDot && !isFirstChar && !alreadyHasADot) ||
(isHyphen && isFirstChar);
if (!isAllowed)
{
e.Handled = true;
}
}
Related
Sorry if this is a really basic question but I'm new to C# and it's my first windows form app.
In the code below my TextBox only accepts a decimal point ",", a minus sign "-", digits, and it also accepts the input of the delete and backspace keys (correct me if I'm wrong). So I can input and delete numbers like:
-12.31
-.31
The problem is I can also input something like:
12-
Is there a way to only input "-" if its the first character of the string? I tried google and I tried to come up with something but nothing seems to work.
And thank you for your time.
private void TextBox_KeyPress(object sender, KeyPressEventArgs e)
{
if (!char.IsDigit(e.KeyChar) && (e.KeyChar != ',') && (e.KeyChar != '-') && (e.KeyChar != (char)8))
{
e.Handled = true;
}
if ((e.KeyChar == ',') && ((sender as TextBox).Text.IndexOf(',') > -1))
{
e.Handled = true;
}
if ((e.KeyChar == '-') && ((sender as TextBox).Text.IndexOf('-') > -1))
{
e.Handled = true;
}
}
You can check where the cursor is by using SelectionStart:
var textBox = (TextBox)sender;
if (e.KeyChar == '-' && (textBox.SelectionStart !=0 || textBox.Text.Contains("-")))
{
e.Handled = true;
}
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.)
I have the following code:
private void txtNR_KeyPress(object sender, KeyPressEventArgs e)
{
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar) && (e.KeyChar != '.'))
{
e.Handled = true;
}
else
{
}
// only allow one decimal point
if ((e.KeyChar == '.') && ((sender as TextBox).Text.IndexOf('.') > -1))
{
e.Handled = true;
}
else
{
MessageBox.Show("You cannot type letters!");
}
}
My question is: when I am trying to type letters the warning message is coming up front but the same is happening when i'm trying to type numbers, and after i click ok on message, the number is writtend down inside. Can you help me understand why?
Your code should be like that:
if (!(char.IsControl(e.KeyChar) || char.IsDigit(e.KeyChar) || (e.KeyChar == '.')))
{
e.Handled = true;
MessageBox.Show("You cannot type letters!");
}
Replace
else { }
with
else
Because of extra {} the second if statement is executed even if first one is handled. Due to this you are seeing message box even if the character is digit (which is already handled)
Your condition is alright. You just need to set the Char to nothing
Try this:
// only allow one decimal point
if ((e.KeyChar == '.') && ((sender as TextBox).Text.IndexOf('.') > -1))
{
e.Handled = true;
}
else
{
MessageBox.Show("You cannot type letters!");
e.KeyChar = '\0';
}
I would suggest you to validate the content of the textbox after the user do his input ont it. Like #Sinatr said, for the user this could be an annoying thing to show a messagebox every time he writes wrong input.
It should also simplify your code, I think.
If the text is not numeric, then display the messagebox, something like that.
textbox_Validating(){
decimal d;
if(decimal.TryParse(textBox1.Text, out d))
{
//valid
}
else
{
//invalid
MessageBox.Show("Please enter a valid number");
return;
}
}
Something like that... Sorry for the eventual errors in the code.
Good luck.
You don't say what your overall aim is.
However to correctly handle the event you are after this will work. You don't really want a pop up message all the time, better validate on form submission.
Are you trying to make a decimal text box ?
You've also got to take into account copy and paste which these events just aren't going to cover.
if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar) && (e.KeyChar != '.'))
{
e.Handled = true;
}
else
{ // only allow one decimal point
if ((e.KeyChar == '.'))
{
if (((TextBox) sender).Text.Contains("."))
{
e.Handled = true;
}
}
else
{
if (char.IsControl(e.KeyChar))
{
return;
}
if (!char.IsDigit(e.KeyChar))
{
MessageBox.Show("You cannot type letters!");
}
}
}
Note: This is not about EXCEPTIONS!
I'm trying to make a textbox accept everything but Symbols and Punctations... but I need to allow "," and "." . I'm using:
if (char.IsPunctuation(e.KeyChar) == true)
{
e.Handled = true;
}
if (char.IsSymbol(e.KeyChar) == true)
{
e.Handled = true;
}
Is there anyway to make an exception for those two Characters ( , and . ) ?
Check for these characters first:
if(e.KeyChar != ',' && e.KeyChar != '.')
{
if (char.IsPunctuation(e.KeyChar))
{
e.Handled = true;
}
if (char.IsSymbol(e.KeyChar))
{
e.Handled = true;
}
}
Note on style: There is no need to compare a boolean to true in order for the branch to be taken.
Try this:
if (char.IsPunctuation(e.KeyChar) && e.KeyChar != ',' && e.KeyChar != '.')
{
e.Handled = true;
}
if (char.IsSymbol(e.KeyChar) && e.KeyChar != ',' && e.KeyChar != '.')
{
e.Handled = true;
}
Or you could simply check it before all of that:
if( e.KeyChar != ',' && e.KeyChar != '.')
{
if (char.IsPunctuation(e.KeyChar) )
{
e.Handled = true;
}
if (char.IsSymbol(e.KeyChar) )
{
e.Handled = true;
}
}
What it does is checks if the character is punctuation/symbol and ALSO the character is NOT ',' or '.'. Therefor the if statement will not run if the character is a comma or period.
I need to get the event args as a char, but when I try casting the Key enum I get completely different letters and symbols than what was passed in.
How do you properly convert the Key to a char?
This is what I've tried
ObserveKeyStroke(this, new ObervableKeyStrokeEvent((char)((KeyEventArgs)e.StagingItem.Input).Key));
Edit: I also don't have the KeyCode property on the args. I'm getting them from the InputManager.Current.PreNotifyInput event.
See How to convert a character in to equivalent System.Windows.Input.Key Enum value?
Use KeyInterop.VirtualKeyFromKey instead.
It takes a little getting used to, but you can just use the key values themselves. If you're trying to limit input to alphanumerics and maybe a little extra, the code below may help.
private bool bLeftShiftKey = false;
private bool bRightShiftKey = false;
private bool IsValidDescriptionKey(Key key)
{
//KEYS ALLOWED REGARDLESS OF SHIFT KEY
//various editing keys
if (
key == Key.Back ||
key == Key.Tab ||
key == Key.Up ||
key == Key.Down ||
key == Key.Left ||
key == Key.Right ||
key == Key.Delete ||
key == Key.Space ||
key == Key.Home ||
key == Key.End
) {
return true;
}
//letters
if (key >= Key.A && key <= Key.Z)
{
return true;
}
//numbers from keypad
if (key >= Key.NumPad0 && key <= Key.NumPad9)
{
return true;
}
//hyphen
if (key == Key.OemMinus)
{
return true;
}
//KEYS ALLOWED CONDITITIONALLY DEPENDING ON SHIFT KEY
if (!bLeftShiftKey && !bRightShiftKey)
{
//numbers from keyboard
if (key >= Key.D0 && key <= Key.D9)
{
return true;
}
}
return false;
}
private void cboDescription_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.LeftShift)
{
bLeftShiftKey = true;
}
if (e.Key == Key.RightShift)
{
bRightShiftKey = true;
}
if (!IsValidDescriptionKey(e.Key))
{
e.Handled = true;
}
}
private void cboDescription_PreviewKeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.LeftShift)
{
bLeftShiftKey = false;
}
if (e.Key == Key.RightShift)
{
bRightShiftKey = false;
}
}
That work for me:
Based on the last entry i found that in WPF there is no such event PreNotifyInput, but i found and equivalent PreviewTextInput
First I try with a RegExp, but I cant make it work, then I use a simple indexOf.
private bool ValidChar(string _char)
{
string Lista = #" ! "" # $ % & ' ( ) * + , - . / 0 1 2 3 4 5 6 7 8 9 : ; < = > ? # A B C D E F G H I J K L M N O P Q R S T U V W X Y Z ";
return Lista.IndexOf(_char.ToUpper()) != -1;
//System.Text.RegularExpressions.Regex RegVal = new System.Text.RegularExpressions.Regex(#"(?<LETRAS>[A-Z]+)+(?<NUMERO>[0-9]+)+(?<CAR>[!|""|#|$|%|&|'|(|)|*|+|,|\-|.|/|:|;|<|=|>|?|#]+)+");
//return RegVal.IsMatch(_char);
}
private void textBoxDescripcion_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
if (!ValidChar(e.Text))
e.Handled = true;
}
I know this is old, but none of the answers seem to actually answer the question. The reason a different char is coming back is because when you just try to cast it to a char you are casting the enum value to a 'char'. However:
var keyPressed = e.key.ToString();
Works great. Returns the key pressed as a string. Then you check the length. If it's == 1 then it's a char, number or symbol. If it's greater than 1 it's a special key.
If you just want the char you can then do keyPressed[0];
This is how I do it.
private void scrollViewer_KeyDown(object sender, KeyEventArgs e)
{
if (!e.IsRepeat)
{
var keyPressed = e.Key.ToString();
if(keyPressed.Length == 1)
CharKeyPressed(keyPressed[0]);
else if(keyPressed.Length > 1)
HandleSpecialKey(keyPressed)
}
}
Inside your PreNotifyInput handler, try something like this:
if (e.StagingItem.Input is System.Windows.Input.TextCompositionEventArgs)
{
if (!String.IsNullOrEmpty((e.StagingItem.Input as System.Windows.Input.TextCompositionEventArgs).Text))
{
Char c = (e.StagingItem.Input as System.Windows.Input.TextCompositionEventArgs).Text[0];
}
}
It raises multiple times for the different routed events, so you may want to filter for a particular one.