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.
Related
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;
}
}
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 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!");
}
}
}
In my window application I need masked textbox which accept real decmal numbers.
eg.
1) 1.56
2) 22.34
3) 123.34
4) 12312.34
This all value should be valid.
Can anyone tell me how can I do this?
And ya if anyone have better solution for real decimal numbers, instead of this masked TextBox
than I love to see it.
Thanks...
Instead of using a MaskedTextbox, consider using NumericUpDown instead. It supports System.Decimal numbers which supports most real-set numbers you should be caring about.
The NumericUpDown.DecimalPlaces property supports up to 99 decimal places.
Use a custom control like this one (modify it to fulfill your needs):
using System;
using System.ComponentModel;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
namespace CustomControls
{
public enum PasteRejectReasons
{
Unknown = 0,
NoData,
InvalidCharacter,
Accepted
}
public class DecimalTextBox : TextBox
{
public const int WM_PASTE = 0x0302;
public event EventHandler<KeyRejectedEventArgs> KeyRejected;
public event EventHandler<PasteEventArgs> PasteRejected;
private bool _DecimalSeparator = false;
private int _Precision;
public new HorizontalAlignment TextAlign
{
get { return base.TextAlign; }
set { base.TextAlign = value; }
}
public int Precision
{
get { return _Precision; }
set { _Precision = value; }
}
public DecimalTextBox()
{
TextAlign = HorizontalAlignment.Right;
Precision = 3;
}
protected override void OnGotFocus(EventArgs e)
{
SelectAll();
base.OnGotFocus(e);
}
protected override void OnKeyDown(KeyEventArgs e)
{
bool validate = true;
if (Text.Contains(".") || Text.Contains(","))
{
int indexSep;
string[] split;
string partiDecimal = "";
if (Text.Contains("."))
indexSep = Text.IndexOf('.');
else
indexSep = Text.IndexOf(',');
split = Text.Split(new char[] { ',', '.' });
partiDecimal += split[1];
if (partiDecimal.Length >= Precision)
if (SelectionStart > Text.Length - (partiDecimal.Length + 1))
validate = false;
}
bool result = true;
bool validateKeys = (e.KeyCode == Keys.Enter);
bool numericKeys = (
((e.KeyCode >= Keys.D0 && e.KeyCode <= Keys.D9) ||
(e.KeyCode >= Keys.NumPad0 && e.KeyCode <= Keys.NumPad9))
&& e.Modifiers != Keys.Shift
&& validate);
bool ctrlA = e.KeyCode == Keys.A && e.Modifiers == Keys.Control;
bool editKeys = (
(e.KeyCode == Keys.Z && e.Modifiers == Keys.Control) ||
(e.KeyCode == Keys.X && e.Modifiers == Keys.Control) ||
(e.KeyCode == Keys.C && e.Modifiers == Keys.Control) ||
(e.KeyCode == Keys.V && e.Modifiers == Keys.Control) ||
e.KeyCode == Keys.Delete ||
e.KeyCode == Keys.Back);
bool navigationKeys = (
e.KeyCode == Keys.Up ||
e.KeyCode == Keys.Right ||
e.KeyCode == Keys.Down ||
e.KeyCode == Keys.Left ||
e.KeyCode == Keys.Home ||
e.KeyCode == Keys.End);
bool decimalSeparator = ((
e.KeyCode == Keys.Decimal ||
e.KeyValue == 190 ||
e.KeyValue == 188)&&
TextLength != 0 &&
SelectionLength == 0);
if (decimalSeparator)
{
if (!_DecimalSeparator)
_DecimalSeparator = true;
else
decimalSeparator = false;
}
if (!(numericKeys || editKeys || navigationKeys || decimalSeparator || validateKeys))
{
if (ctrlA)
SelectAll();
result = false;
}
if (!result)
{
e.SuppressKeyPress = true;
e.Handled = true;
if (!ctrlA)
OnKeyRejected(new KeyRejectedEventArgs(e.KeyCode));
}
else
base.OnKeyDown(e);
}
protected override void OnKeyPress(KeyPressEventArgs e)
{
if (e.KeyChar == ';' || e.KeyChar == '?')
{
if (!(Text.Contains(",") || Text.Contains(".")))
_DecimalSeparator = false;
e.Handled = true;
}
}
protected override void OnTextChanged(EventArgs e)
{
bool invalid = false;
int i = 0;
foreach (char c in Text) // Check for any non digit characters.
{
if (!(char.IsDigit(c) || c == ',' || c == '.'))
{
invalid = true;
break;
}
if (c == ',' || c == '.')
i++;
}
if (i == 0)
_DecimalSeparator = false;
else if (i > 1)
invalid = true;
if (invalid)
{
Text = "";
return;
}
if (Text.Contains(".") || Text.Contains(","))
{
string charSep = "";
string[] split;
string partiEntier = "";
if (Text.Contains("."))
charSep = ".";
else
charSep = ",";
split = Text.Split(new char[] { ',', '.' });
partiEntier += split[0];
if (partiEntier == "")
Text = "0" + charSep + split[1];
}
base.OnTextChanged(e);
}
protected override void WndProc(ref Message m)
{
if (m.Msg == WM_PASTE)
{
PasteEventArgs e = CheckPasteValid();
if (e.RejectReason != PasteRejectReasons.Accepted)
{
m.Result = IntPtr.Zero;
OnPasteRejected(e);
return;
}
}
base.WndProc(ref m);
}
private PasteEventArgs CheckPasteValid()
{
PasteRejectReasons rejectReason = PasteRejectReasons.Accepted;
string originalText = Text;
string clipboardText = string.Empty;
string textResult = string.Empty;
try
{
clipboardText = Clipboard.GetText(TextDataFormat.Text);
if (clipboardText.Length > 0)
{
textResult = (
Text.Remove(SelectionStart, SelectionLength).Insert(SelectionStart, clipboardText));
foreach (char c in clipboardText)
{
if (!char.IsDigit(c))
{
rejectReason = PasteRejectReasons.InvalidCharacter;
break;
}
}
}
else
rejectReason = PasteRejectReasons.NoData;
}
catch
{
rejectReason = PasteRejectReasons.Unknown;
}
return new PasteEventArgs(originalText, clipboardText, textResult, rejectReason);
}
protected virtual void OnKeyRejected(KeyRejectedEventArgs e)
{
EventHandler<KeyRejectedEventArgs> handler = KeyRejected;
if (handler != null)
handler(this, e);
}
protected virtual void OnPasteRejected(PasteEventArgs e)
{
EventHandler<PasteEventArgs> handler = PasteRejected;
if (handler != null)
handler(this, e);
}
}
}
I am trying to disable all keystrokes entered into a text box except the following:
0 1 2 3 4 5 6 7 8 9 . (so all keys except the numbers and the '.' should be disabled)
Right now I have the following code but it only checks to see if a letter was entered as the first value (not to mention its really sloppy):
private void yDisplacementTextBox_TextChanged(object sender, EventArgs e)
{
if (yDisplacementTextBox.Text.ToUpper() == "A" || yDisplacementTextBox.Text.ToUpper() == "B" || yDisplacementTextBox.Text.ToUpper() == "C" ||
yDisplacementTextBox.Text.ToUpper() == "D" || yDisplacementTextBox.Text.ToUpper() == "E" || yDisplacementTextBox.Text.ToUpper() == "F" ||
yDisplacementTextBox.Text.ToUpper() == "G" || yDisplacementTextBox.Text.ToUpper() == "H" || yDisplacementTextBox.Text.ToUpper() == "I" ||
yDisplacementTextBox.Text.ToUpper() == "J" || yDisplacementTextBox.Text.ToUpper() == "K" || yDisplacementTextBox.Text.ToUpper() == "L" ||
yDisplacementTextBox.Text.ToUpper() == "M" || yDisplacementTextBox.Text.ToUpper() == "N" || yDisplacementTextBox.Text.ToUpper() == "O" ||
yDisplacementTextBox.Text.ToUpper() == "P" || yDisplacementTextBox.Text.ToUpper() == "Q" || yDisplacementTextBox.Text.ToUpper() == "R" ||
yDisplacementTextBox.Text.ToUpper() == "S" || yDisplacementTextBox.Text.ToUpper() == "T" || yDisplacementTextBox.Text.ToUpper() == "U" ||
yDisplacementTextBox.Text.ToUpper() == "V" || yDisplacementTextBox.Text.ToUpper() == "W" || yDisplacementTextBox.Text.ToUpper() == "X" ||
yDisplacementTextBox.Text.ToUpper() == "Y" || yDisplacementTextBox.Text.ToUpper() == "Z")
{
MessageBox.Show("Please enter a numeric value for the Y Displacement.", "Y Displacement: Numbers Only Error",
MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
Is there anyway to have it so when pressed, all of the keys on the keyboard (except the numbers and the period button) do not register (or disables) the actual value of the key and inputs nothing?
Use textBox1.KeyPress += textBox1_KeyPress
This code only allowing numbers and . and the backspace.
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if ((e.KeyChar > (char)Keys.D9 || e.KeyChar < (char)Keys.D0) && e.KeyChar != (char)Keys.Back && e.KeyChar != '.')
{
e.Handled = true;
}
//Edit: Alternative
if (!char.IsDigit(e.KeyChar) && e.KeyChar != (char)Keys.Back && e.KeyChar != '.')
{
e.Handled = true;
}
}
There are two ways you could try to approach this:
Wait for the user to finish entering the data, then use double.TryParse() to make sure it's a valid number.
Use the KeyPress event of the TextBox to validate the data as each key is pressed.
Take a look here: Simple Numeric TextBox
EDIT: As other answers explains what to do dealing with OnKeyPress/OnKeyDown events, this article demonstrates how to deal with other scenarios, as pasting text, so I'll keep this answer.
You should hook into the KeyDown and KeyPress event to prevent the input of unwanted characters. There is a sample on MSDN
Many third party control libraries also have this kind of functionality built in if you ever find yourself using one of them.
It is better practice to allow typing anything but give notification through an error provider about the failing validation (Validating event and double.TryParse()).
But if you insist, be sure to replace the '.' with the decimal separator of the system. If you are not assuming all values to be English you can easily get into a cannot-enter-a-decimal-value problem.
For instance, I am in Croatia and here we have to type a comma (,). In some islamic country I fail to remember the decimal separator is a hash (#).
So beware of localization issues.
The below code will suppress all but number, the backspace, and the decimal. It also only allows a single decimal for numeric entry.
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if ((e.KeyChar > (char)Keys.D9 || e.KeyChar < (char)Keys.D0) && e.KeyChar != (char)Keys.Back && e.KeyChar != '.')
{
e.Handled = true;
return;
}
if(e.KeyChar == '.' && textBox1.Text.Contains('.'))
{
e.Handled = true;
}
}
This also can be used
if (!Char.IsDigit(e.KeyChar) && e.KeyChar != '\b' && e.KeyChar != '.'){
e.Handled = true;}
Shortest fix to make text/cmb box read-only, attach following to respective keypress event :
private void cmbDisable_KeyPress(object sender, KeyPressEventArgs e)
{
e.KeyChar = (char)(0);
}