I'm setting SuppressKeyPress = true when a user presses the ENTER/RETURN key in a MaskedTextBox to prevent the annoying beep that is normally made. This works great, but when I clear my form the MaskedTextBox no longer behaves as expected. The first character entered is a phantom character that disappears after the 2nd character is entered.
Example:
__.___
Set text = "0"
0_.___
User enters text
09.999
User presses ENTER
User presses Save & Next (this clears the form)
Reset text = "0"
0_.___
User enters first 9
09_.___
User enters second 9
0_.9__
If the user TABS out of the MaskedTextBox instead of pressing ENTER, this works fine (the text is entered correctly without any odd shifting.) The only differences I can find are that I'm using SuppressKeyPress and that the flagState in Non-Public Members is different (2052 when I do NOT SuppressKeyPress and 2048 when I DO SuppressKeyPress.)
Is there a way to either prevent the BEEP without breaking the MaskedTextBox or a way to fix the MaskedTextBox after SuppressKeyPress (I've tried most if not all the methods on the MaskedTextBox itself: refreshText, refresh, etc...)
Here is the MaskedTextBox definition and the KeyDown method:
//
// aTextBox
//
this.aTextBox.Location = new System.Drawing.Point(130, 65);
this.aTextBox.Mask = "##.###";
this.aTextBox.Name = "aTextBox";
this.aTextBox.Size = new System.Drawing.Size(50, 20);
this.aTextBox.TabIndex = 3;
this.aTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.general_KeyDown);
this.aTextBox.Leave += new System.EventHandler(this.validate);
general_KeyDown looks like this:
private void general_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
e.Handled = true;
e.SuppressKeyPress = true;
SendKeys.Send("{TAB}");
}
}
I can't repro but I definitely see it in the reference source. MaskTextBox is also looking for Keys.Enter and sets and internal flag when it sees it, a flag that affects the key handling for subsequent keystrokes. Your code may well mess this up.
Make sure that the control doesn't see the keystroke at all by overriding OnKeyDown. That requires inheriting your own control, like this:
using System;
using System.Windows.Forms;
class MyMaskTextBox : MaskedTextBox {
protected override void OnKeyDown(KeyEventArgs e) {
if (e.KeyData == Keys.Enter) {
e.Handled = e.SuppressKeyPress = true;
this.Parent.GetNextControl(this, true).Select();
return;
}
base.OnKeyDown(e);
}
}
Paste the code in a new class and compile. Drop the new control from the top of the toolbox, replacing your old one.
Related
How to do the event handling when the user presses the ENTER key or leaves the focus on the particular textbox? I tried for KeyChanged event, but it will keep updating the number instead of only once when complete.
private void txtNumber_TextChanged(object sender, EventArgs e)
{
txtNumber.Text = double.Parse(txtNumber.Text).ToString("F2");
}
There are a few issues with the posted code. One issue is that doing the formatting each time the user “types” a character is going to be awkward for the user. In addition, if the user presses the “Enter” key, the event txtNumber_TextChanged is not going to fire. I assume you may already know this.
Next, when getting input from users, it is imperative that you check the input for valid numbers BEFORE calling the parse method…Example, the line of code…
double.Parse(txtNumber.Text).ToString("F2");
Will FAIL and crash the program if the text in the text box… txtNumber.Text is NOT a valid double.
You should always assume the user is going to make a mistake and you don’t want your code to crash when they do.
Therefore I suggest using the double.TryPasre method to avoid these possible crashes, calling this method will NEVER throw an exception and will make validating the number easier.
To get what you want I recommend you wire up three (3) events for the text box…
The Leave event, this is used to format the text, when the user leaves the text box, like when they click on another control.
Next is the PreviewKeyDown event, this is used when the user presses the “Enter” key.
And one extra event to help the user ONLY add numbers and one dot. The KeyPressed event is wired up and will ignore any pressed keys that are not numbers or the dot (period). Also, it will only allow one period, if the user tries to add a second decimal place, it will be ignored.
Bear in mind, the key pressed event helps by preventing the user from “typing” alpha text into the text box… however, the user can still paste text. Fortunately, since we are using the TryParse method, when the pasted text is an invalid number, the try parse will simply return “0.00” and NOT crash the code.
private void txtNumber_Leave(object sender, EventArgs e) {
double.TryParse(txtNumber.Text.Trim(), out double number);
txtNumber.Text = number.ToString("F2");
}
private void txtNumber_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) {
if (e.KeyCode == Keys.Enter) {
double.TryParse(txtNumber.Text.Trim(), out double number);
txtNumber.Text = number.ToString("F2");
}
}
private void txtNumber_KeyPress(object sender, KeyPressEventArgs e) {
if (!char.IsControl(e.KeyChar) // <- key pressed is not a control key
&& !char.IsDigit(e.KeyChar) // <- key pressed is not a digit (number)
&& e.KeyChar != '.') { // <- key pressed is not a dot (.)
e.Handled = true; // <- if its not a control key, digit or dot... then ignore it
}
// only allow one decimal point - if there is already a dot, then ignore the second one
if (e.KeyChar == '.' && txtNumber.Text.IndexOf('.') > -1) {
e.Handled = true; // <- if there is already a dot in the text... then ignore it
}
}
Formatting a text value in a TextBox must be done once the input is already done.
TextChanged, occurs when the Text property value changes. So this is not ideal.
The only event you can rely on.
LostFocus, occurs when the control loses focus. You can sheck some info when control change focus.
private void textBox1_LostFocus(object sender, System.EventArgs e)
{
// Code here
}
Sometimes we wanted the format to be changed once we click something on the keyboard, so here are the possible events for that.
The non-character keys do raise the KeyDown and KeyUp events.
KeyDown, occurs when a key is pressed while the control has focus.
KeyUp, occurs when a key is released while the control has focus.
KeyPress, occurs when a character. space or backspace key is pressed while the control has focus.
Note: When using the KeyPress you need to also consider if the Form is the one handling the input events first or not, check the Remarks here.
private void textBox1_KeyUp(object sender, System.Windows.Forms.KeyEventArgs e)
{
if (e.KeyCode == Keys.Return) // You can also use: e.KeyValue == 13
{
// Do your code here
}
};
I am using c# window form application. I have already tried many example on the internet for this query but nothing works for me. I just want to replace the action of Enter key with Tab key on a Window Forms. I don't want to apply keydown or up event on one by one on my textbox. I just want a single event which I can apply on my window form.
Thanks.
It works fine now I used these code of lines on form keyup event, and set the KeyPreview property True.
if (e.KeyData == System.Windows.Forms.Keys.Enter)
{
SendKeys.Send("{TAB}");
}
Create your own custom TextBox:
public class MyTextBox : TextBox
{
protected override void OnKeyDown(KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
Parent.SelectNextControl(this, true, true, true, true);
e.Handled = true;
e.SuppressKeyPress = true; // suppress Ding sound
}
base.OnKeyDown(e);
}
}
Compile the code. This component will appear in the toolbar. Use it instead of the regular textboxes.
How can I replace pressed 'decimal point' key from numpad to always return '.' independent of regional setting. I want that works only for one (specific) TextBox not all in application.
It's possible to accomplished this without creating own control?
This is a possible solution (most possibly not the best one, but one that should work) that would add a . character to a textbox if the decimal key on the numpad is pressed, if the , key is pressed it still adds the , character to the textbox.
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Decimal)
{
e.SuppressKeyPress = true;
textBox1.Text += ".";
textBox1.SelectionStart = textBox1.Text.Length;
textBox1.SelectionLength = 0;
}
}
The SuppressKeyPress prevents that the pressed key is sent to the textbox. Then you add the desired character to the textbox. The SelectionStart and SelectionLength properties are set to move the cursor to the end of the string in the textbox.
Hope that helps
EDIT:
As cdkMoose pointed out the flaw with this approach is that the .character is always added to the end of the string, if it is desired to add the .character anywhere in the string the code could be used like this:
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Decimal)
{
e.SuppressKeyPress = true;
var caretPosition = textBox1.SelectionStart;
textBox1.Text.Insert(caretPosition , ".");
textBox1.SelectionStart = caretPosition + 1;
textBox1.SelectionLength = 0;
}
}
In order to do this, you simply need to handle the KeyDown event, supress the activated key if its the numpad decimal, and then simply send the new key you want.
It's pretty straightforward, the following links should give you enough pointers to actually write some code:
Keys
Control.KeyDown
KeyEventArgs
SendKeys
Once you've written something, you can ask a new question about any specific dificulties you might encounter.
Look at this.
You can handle KeyDown event and if is , on numpad cancel event and send new with '.'.
I want to prevent the Enter key from making a new line inside the multiple line text box using the KeyDown event. Despite clearing the textBox using textBox.Text = "" or textBox.Clear(), it behaves like this: http://i.imgur.com/3sknAbO.png
private void textBox2_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
listBox1.Items.Add(textBox2.Text);
textBox2.Text = "";
}
}
So, basically you want to define a text box as multi-line and only accept one long line from it?
Seems as though you only want a single line text box. Define your text box as single line and set it up at design time to look like a multi-line text box.
Another option would be to leave the box as-is and allow the user to enter it with the newline characters in it. Then, when you need the data, simply remove all newline characters after the fact.
I was experimenting a bit and it seems like the new line from the Enter key is added at the KeyUp event. So this should work (note that I use KeyUp instead of KeyDown):
private void textBox2_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
listBox1.Items.Add(textBox2.Text);
textBox2.Text = "";
e.Handled = true;
}
}
Or you could set the cursor position with
textBox2.Select(0, 0);
instead of using the line e.Handled = true;
I have the following code:
private void richTextBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.N)
{
richTextBox1.Select(1, 3);
}
}
When I press the N key , the selected text is replaced with "n". I read this Selecting text in RichTexbox in C# deletes the text ,but it had no effects.
I am using Windows Forms.
Likely, you will need e.Handled = true; in this to stop the event.
http://msdn.microsoft.com/en-us/library/system.windows.forms.keyeventargs.handled.aspx
private void richTextBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.N)
{
richTextBox1.Select(1, 3);
e.Handled = true;
}
}
Try it yourself:
Open up the editor, type some text, mark some of this text and press N. What happens? The marked text is replaced with n.
The same thing happens in your RichTextBox. Important to understand here is, that with the event you set up, you only add some functionality and leave the default event handling (handled by the OS) intact.
So with your code, on a key press you just do
richTextBox1.Select(1, 3);
which selects some characters and afterwards the default event handling kicks in. Thus there is some marked text which gets replaced with N.
So, you simply have to mark the event as handled by yourself. Not using the Handled-property, but with the SuppressKeyPress-property.
private void richTextBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.N)
{
richTextBox1.Select(1, 3);
e.SuppressKeyPress = true;
}
}
The documentation of Handled clearly states:
If you set Handled to true on a TextBox, that control will
not pass the key press events to the underlying Win32 text
box control, but it will still display the characters that the user typed.
Here is the official documentation of SuppressKeyPress.