I am using this code to block some keys in text box.
private void tb_MyTextBox_KeyDown(object sender, KeyEventArgs e)
{
// Handle Shift case
if (Keyboard.Modifiers == ModifierKeys.Shift)
e.Handled = true;
// Handle all other cases
if (!e.Handled && (e.Key < Key.D0 || e.Key > Key.Z))
{
if (e.Key < Key.NumPad0 || e.Key > Key.NumPad9)
{
if (e.Key != Key.Back)
e.Handled = true;
}
}
}
This code blocks all the keys except A to Z and 0 to 9. But I also want to allow _ which you get by Shift + _ .
How to do this for only Shift + _ ?????
(All the code is on KeyDown event of Siverlight)
I don't like the idea of checking the KeyPress args, since there are LOTS of cases it doesn't account for (such as alternate keyboard layouts, CAPS LOCK being on, or pasting text from the clipboard).
I see two ways of doing this properly:
Create a behaviour that you attach to the TextBox. The behaviour would keep track of the current text, and subscribe to the TextChanged event. Whenever the event fires, the behaviour would ensure the text is valid, and if not, just set the text back to the last valid value it saw.
Create a subclass of TextBox, in which you override the OnTextInput() method. Here you can do whatever checks you want, and if you don't like the text that was input (e.Text), just set e.Handled = true and the input will be ignored.
You can do it like that:
if ((e.Modifiers == Keys.Shift) && (e.KeyCode == Keys.OemMinus))
{
// Do Something
}
Related
private void UserInputText_KeyDown(object sender, KeyEventArgs e)
{
if ((e.KeyCode == Keys.D4 && e.Modifiers == Keys.Shift) || (e.KeyCode == Keys.Add))
{
if (String.IsNullOrEmpty(UserInputText.Text))
{
MessageBox.Show("Bir sayı giriniz.");
UserInputText.Clear();
return;
}
if (double.TryParse(UserInputText.Text, out sayı1))
{
CalculationResultText.Text = sayı1 + " + ";
islem = "+";
UserInputText.Clear();
}
else
{
MessageBox.Show("Sadece sayı değeri girebilirsiniz.");
UserInputText.Clear();
}
}
}
I am coding a basic forms calculator. I am trying to trigger addition function and clear the textbox when textbox is focused and user presses "+" key. "if (String.IsNullOrEmpty(UserInputText.Text)) and else conditions work well. But if no Message boxes shows up as in the
if (double.TryParse(UserInputText.Text, out sayı1)) condition, the "+" character remains in the textbox as in the image. Thanks for help.
If I understand correctly, you want to first check the character that was typed in and if it's incorrect then you want to prevent this character from appearing?
If so, then you need to set e.Handled = true property when you want to prevent it.
This call tells the GUI element (your TextBox) that "I did all the checks for this event (i.e. KeyDown event), and I don't want you to contribute in handling of this event (i.e. normally the TextBox would try to add this character to its Text property, but you prevent it)".
Check out documentation on KeyEventArgs.Handled.
KeyPress event enables you to prevent any further changes in the TextBox.
You can do that thanks to Handled property of KeyPressEventArgs
private void UserInputText_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == '+')
{
UserInputText.Clear();
e.Handled = true;
}
}
I am using the following textbox keypress() event to capture the keystrokes entered by user to restrict user to enter alphabet and numeric values.
private void textBoxName_KeyPress(object sender, KeyPressEventArgs e)
{
e.Handled = !(char.IsLetter(e.KeyChar) ||
e.KeyChar == (char)Keys.Space ||
e.KeyChar == (char)Keys.Back ||
e.KeyChar==(char)Keys.ControlKey );
}
Now the problem is by using the above mentioned code I am not able to use shortcut keys like Ctrl+C or Ctrl+v even if keys.ControlKey is handled in the the keypress event.
What i am doing wrong here?
Thanks in advance.
The Keypress event is not raised if the Control key is pressed without any other key. Is used as a key modifier only. In this case, e.KeyChar returns a modified value that char.IsLetter() considers false, the ! operator transforms it in true and assigns it to e.Handled, thus the keypress event is canceled.
to capture the keystrokes entered by user to restrict user to enter
alphabet and numeric values.
If, as you said, numbers are part of the required input, char.IsLetterOrDigit() should be used instead of char.IsLetter().
And punctuation? Is part of the input too?
These symbols are considered punctuation by char.IsPunctuation(): \"%&/()?*#.,:;_-'
Two methods to have the same result.
In both, char.IsControl(e.KeyChar) is used to check if Control is part of the Keycode and if it is, strip it by XOR(ing) it.
1) Filter using a simple regex. This one gives you more control on what to filter.
Regex _KeyFilter = new Regex(#"^[a-zA-Z0-9.,]");
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar != (char)Keys.Back && e.KeyChar != (char)Keys.Return && e.KeyChar != (char)Keys.Space)
{
e.Handled = !_KeyFilter.IsMatch((char.IsControl(e.KeyChar)
? (char)(e.KeyChar ^ 64)
: e.KeyChar).ToString());
}
}
2) Filtert using char.IsLetterOrDigit() and char.IsPunctuation()
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar != (char)Keys.Back && e.KeyChar != (char)Keys.Return && e.KeyChar != (char)Keys.Space)
{
char _keypress = char.IsControl(e.KeyChar) ? (char)(e.KeyChar ^ 64) : e.KeyChar;
e.Handled = !char.IsLetterOrDigit(_keypress) && !char.IsPunctuation(_keypress);
}
}
I have a textbox in my application which I only want the user to be able to choose the "minus", "comma", "digits" and "back" from the keyboard. Can only make the user use digits and the back key, the rest doesn't work.
private void BoxMaxY_KeyPress(object sender, KeyPressEventArgs e)
{
if (!(Char.IsDigit(e.KeyChar) || e.KeyChar == (char)Keys.Back ||
!(e.KeyChar == (char)Keys.OemMinus || !(e.KeyChar == (char)Keys.Oemcomma))))
{
e.Handled = true;
}
}
Because your code says: handle if it's not minus or not comma, remove the "!" from those checks.
Take a simple messaging program, such as Steam friend conversation.
When you hit ENTER, the message is sent, and the message field is emptied.
When you enter CTRL/SHIFT + ENTER a newline is created. If your cursor is not at the end of the input text, then all the text appearing after your cursor will be sent to a newline.
Well, how do you accomplish such a feat ?
Furthermore, I'd like to know how to have the aforementioned features and also how to still be able to paste a multiline text into the message field.
For now, this is my code. It's something but does not get all the job done :
private bool ctrlOrShift = false;
private void MessageField_KeyDown( object sender, KeyEventArgs e )
{
if( e.Key == Key.LeftCtrl || e.Key == Key.LeftShift )
{
ctrlOrShift = true;
}
else if( e.Key == Key.Enter && ctrlOrShift != true && !MessageField.AcceptsReturn )
{
AsyncSendMessage();
}
else if( e.Key == Key.Enter && ctrlOrShift != true && MessageField.AcceptsReturn )
{
MessageField.AcceptsReturn = false;
}
else if( e.Key == Key.Enter && ctrlOrShift == true )
{
ctrlOrShift = false;
MessageField.AcceptsReturn = true;
MessageField.Text += System.Environment.NewLine;
MessageField.Select( MessageField.Text.Length, 0 );
MessageField.AcceptsReturn = false;
}
else
{
ctrlOrShift = false; // Canceled because follow-up key wat not ENTER !
}
}
The following scenarios occur :
Using CTR or SHIFT, I can create a new line in my TextBox :) ;
I cannot paste a multiline text from the Clipboard: only the first line will be pasted, nothing else :( ;
If I use CTRL + V to paste content, the MessageField_KeyDown event takes the CTRL hit is taken into account, therefore, if I press ENTER, message is not sent but a newline is created instead :/ (in a case where you would paste a content and send it right away) ;
If my cursor position is before the end of the input text, CTR/SHIT + ENTER will create a newline at the end of the text regardless of the cursor position :/
So, how can I tweak this code ? Thanks for the help !
The Result of the Solution is this:
Normal
After one SHIFT + ENTER
When you push ENTER it looks like in Normal only without text in the box
As mentioned in the comments you could use the AcceptsReturn and TextWrapping properties for a multiline textbox (like in steam).
Use Height = Auto for a better looking one (otherwise you only have one line and all other lines disappear)
XAML
for Textbox:
<TextBox HorizontalAlignment="Left" Height="Auto" Margin="10,10,0,0"
TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top"
Width="497" AcceptsReturn="True"
KeyDown="TextBoxKeyDown" PreviewKeyDown="TextBoxPreviewKeyDown"/>
Event Handler:
This is not that easy as i thought first :'D But i figured it out.
When you use the AcceptsReturn Property the Enter Key is Handeled by the AcceptsReturn. So if you push enter you will see a new line instead of a Send() if you programm is like this:
private void TextBoxKeyDown(object sender, KeyEventArgs e)
{
var textbox = sender as TextBox;
// This will never happen because the Enter Key is handeled before
// That means TextBoxKeyDown is not triggered for the Enter key
if (e.Key == Key.Enter &&
!(Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)) &&
!(Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.LeftShift)))
{
// Send(textBox.Text)
textbox.Text = "";
}
}
So you need to implement the PreviewKeyDown eventhandler. Because in the PreviewKeyDown event handler the Event is routed through the (Parent)Elements.
Look at this Answer
Also note the e.Handled = true line. Otherwise the Enter is routed through the method to the AcceptsReturn and you will have 2 lines after the enter, but the Textbox is empty.
With this method the KeyDown Method is no longer needed!
private void TextBoxPreviewKeyDown(object sender, KeyEventArgs e)
{
// Enter key is routed and the PreviewKeyDown is also fired with the
// Enter key
var textbox = sender as TextBox;
// You don't want to clear the box when CTRL and/or SHIFT is down
if (e.Key == Key.Enter &&
!(Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl)) &&
!(Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift)))
{
textbox.Text = "";
e.Handled = true;
}
}
The pros of the Multiline Textbox is that you can copy and paste
+ you have no problems with CTRL pushed or not.
What do you think about it?
Hope it helps
This question already has answers here:
numeric-only textbox as a control in Visual Studio toolbox
(4 answers)
Closed 9 years ago.
I am using C#.NET 3.5, and I have a problem in my project. In C# Windows Application, I want to make a textbox to accept only numbers. If user try to enter characters message should be appear like "please enter numbers only", and in another textbox it has to accept valid email id message should appear when it is invalid. It has to show invalid user id.
I suggest, you use the MaskedTextBox: http://msdn.microsoft.com/en-us/library/system.windows.forms.maskedtextbox.aspx
From C#3.5 I assume you're using WPF.
Just make a two-way data binding from an integer property to your text-box. WPF will show the validation error for you automatically.
For the email case, make a two-way data binding from a string property that does Regexp validation in the setter and throw an Exception upon validation error.
Look up Binding on MSDN.
use this code:
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
const char Delete = (char)8;
e.Handled = !Char.IsDigit(e.KeyChar) && e.KeyChar != Delete;
}
You might want to try int.TryParse(string, out int) in the KeyPress(object, KeyPressEventArgs) event to check for numeric values. For the other problem you could use regular expressions instead.
I used the TryParse that #fjdumont mentioned but in the validating event instead.
private void Number_Validating(object sender, CancelEventArgs e) {
int val;
TextBox tb = sender as TextBox;
if (!int.TryParse(tb.Text, out val)) {
MessageBox.Show(tb.Tag + " must be numeric.");
tb.Undo();
e.Cancel = true;
}
}
I attached this to two different text boxes with in my form initializing code.
public Form1() {
InitializeComponent();
textBox1.Validating+=new CancelEventHandler(Number_Validating);
textBox2.Validating+=new CancelEventHandler(Number_Validating);
}
I also added the tb.Undo() to back out invalid changes.
this way is right with me:
private void textboxNumberic_KeyPress(object sender, KeyPressEventArgs e)
{
const char Delete = (char)8;
e.Handled = !Char.IsDigit(e.KeyChar) && e.KeyChar != Delete;
}
TRY THIS CODE
// Boolean flag used to determine when a character other than a number is entered.
private bool nonNumberEntered = false;
// Handle the KeyDown event to determine the type of character entered into the control.
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
// Initialize the flag to false.
nonNumberEntered = false;
// Determine whether the keystroke is a number from the top of the keyboard.
if (e.KeyCode < Keys.D0 || e.KeyCode > Keys.D9)
{
// Determine whether the keystroke is a number from the keypad.
if (e.KeyCode < Keys.NumPad0 || e.KeyCode > Keys.NumPad9)
{
// Determine whether the keystroke is a backspace.
if (e.KeyCode != Keys.Back)
{
// A non-numerical keystroke was pressed.
// Set the flag to true and evaluate in KeyPress event.
nonNumberEntered = true;
}
}
}
}
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (nonNumberEntered == true)
{
MessageBox.Show("Please enter number only...");
e.Handled = true;
}
}
Source is http://msdn.microsoft.com/en-us/library/system.windows.forms.control.keypress(v=VS.90).aspx
You can check the Ascii value by e.keychar on KeyPress event of TextBox.
By checking the AscII value you can check for number or character.
Similarly you can write logic to check the Email ID.
I think it will help you
<script type="text/javascript">
function isNumberKey(evt) {
var charCode = (evt.which) ? evt.which : event.keyCode
if (charCode > 32 && (charCode < 48 || charCode > 57) && (charCode != 45) && (charCode != 43) && (charCode != 40) && (charCode != 41))
return false;
return true;
}
try
{
int temp=Convert.ToInt32(TextBox1.Text);
}
catch(Exception h)
{
MessageBox.Show("Please provide number only");
}