I have a form that has several buttons. I have KeyPreview set to true, and I have Keydown, KeyPress, and keyup events all reading
form_keyevent(object sender, System.Windows.Forms.KeyPressEventArgs e)
{
e.handled = true;
}
For some reason, the enter key still clicks a button that has focus. What am I missing? Is there a way around it?
Pressing the Enter key on a Form with a focused button invokes the Form.ProcessCmdKey method:
This method is called during message preprocessing to handle command keys. Command keys are keys that always take precedence over regular input keys. Examples of command keys include accelerators and menu shortcuts.
You can override this method to mark the key as handled:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
// if enter pressed, return 'true' to skip default handler
if ((keyData & Keys.Return) == Keys.Return)
return true;
return base.ProcessCmdKey(ref msg, keyData);
}
If you only want to ignore Enter when buttons are focused, you can use something like:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
// if a button is focused AND enter pressed, skip default handler
if (this.ActiveControl is Button && (keyData & Keys.Return) == Keys.Return)
return true;
return base.ProcessCmdKey(ref msg, keyData);
}
This could be happening if your button is set as the AcceptButton property on the form. If that is the case, just clear that property.
In addition to the other answers You can add a KeyDown event handler to your form, in its KeyEventArgs there is a SuppressKeyPress property which will prevent your Keypress from being sent to the parent control.
also see this SO question for what the differences are between handled and SuppressKeyPress,
From the SuppressKeyPress Link:
Gets or sets a value indicating whether the key event should be passed on to the underlying control.
example:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.Enter )
e.SuppressKeyPress = true;
}
Related
I am trying to bind a keyboard button (preferably "ESC") to stop the code that is running inside the method. But the thing is, it only works with actual buttons, is there anyway to bypass this so it works when pressing labels aswell?
private void label1_Click(object sender, EventArgs e)
{
if (e.Control && e.KeyCode.ToString() == "ESC")
{
MessageBox.Show("This does now work");
}
}
I've read somewhere that it is possible its just that the Visual Studio GUi doesnt provide it, but you can do it with code somehow, is this true?
I am not sure what you are trying to do. The following will get the Escape key when it is pressed when the focus is in the form regardless of what control has the focus. Just add this to the form (the code of course).
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == (Keys.Escape))
{
MessageBox.Show("This works");
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
I have set the "ENTER" key as a "TAB" key in windows form.
following is the code
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
KeyEventArgs e = new KeyEventArgs(keyData);
if (e.KeyCode == Keys.Enter)
{
SendKeys.Send("{TAB}");
}
if (e.KeyCode == Keys.Escape)
{
this.Close();
}
return base.ProcessCmdKey(ref msg, keyData);
}
its working perfectly with all controls but when I press ENTER on any combobox then it takes two tab indexes.
eg.
textbox1
combobox
textbox2
textbox3
textbox4
when i press ENTER to leave combobox then the cursor(FOCUS) is directly comes to the textbox 3
i want that focus to the next control of combobox , i.e, textbox 2
please help me
thanks in advance..!
Just return true; after you send the Tab:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
KeyEventArgs e = new KeyEventArgs(keyData);
if (e.KeyCode == Keys.Enter)
{
SendKeys.Send("{TAB}");
return true;
}
if (e.KeyCode == Keys.Escape)
{
this.Close();
}
return base.ProcessCmdKey(ref msg, keyData);
}
Control.TabIndex property decides that which order the control should get focused when a Tab key is pressed.
You should set TabIndex properties of controls in a order that you would like them to focus based on Tab key press.
That said, you shouldn't use SendKeys.Send("{TAB}") method for simulating a Tab key press. You should use Control.SelectNextControl method for this purpose.
I have a winform application which has two text boxes and a button. If the control focus is on any of the text boxes and user clicks keyboard "enter" button. The button event should invoke.
The issue is I couldn't find the TextBox_KeyDown to capture the "Enter" key press. In the Visual Studio editor, KeyDown,KeyPress,Keyup properties are empty.
A couple things. It sounds to me like you just need to set the AcceptButton on the Form to the button you want clicked when the user presses Enter. It will be handled automatically for you.
Second, if that's not the case, then you need to set the KeyPreview to true on the Form and handle the ProcessCmdKey method on the Form:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Enter)
{
// do something
}
else
{
base.ProcessCmdKey(ref msg, keyData);
}
}
you can do it like this?
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
}
}
VS2010 C# .Net 4.1
I am working on a form that the user must select or enter initial data in a ComboBox. Using the code below, which took some time to deduce, I enable the Edit button when the user hits the Tab key if the data is correct, otherwise the button is disabled it moves to the next button.
This code works, but a side effect is that the PreviewKeyDown event reoccurs when I set IsInputKey to true. This calls validation twice. The KeyDown event is only called once, and the IsInputKey is false again on the second call so I do need to check validation again.
I'd like to understand why and possibly avoid it.
private void comboBox1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e) {
if (e.KeyData == Keys.Tab) {
if (ValidationRoutine()) {
e.IsInputKey = true; //If Validated, signals KeyDown to examine this key
} //Side effect - This event is called twice when IsInputKey is set to true
}
}
private void comboBox1_KeyDown(object sender, KeyEventArgs e) {
if (e.KeyData == Keys.Tab) {
e.SuppressKeyPress = true; //Stops further processing of the TAB key
btnEdit.Enabled = true;
btnEdit.Focus();
}
}
The why? is hard to answer, Winforms just does. First from the message loop, again from the control's message dispatcher. The event was really meant as an alternative way to implement the protected IsInputKey() method without having to override the control class. Bit of a hack, I always override and never used the event.
The better mouse trap is to override ProcessCmdKey() instead. Like this:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
if (this.ActiveControl == comboBox1 && keyData == Keys.Tab) {
if (ValidationRoutine()) {
btnEdit.Enabled = true;
btnEdit.Focus();
return true;
}
}
return base.ProcessCmdKey(ref msg, keyData);
}
I have a form with a single text box on it. No other controls. Whenever I type the 'Enter' key or the 'Esc' key, the form functions as I desire; but I hear that horrible Windows error sound. The code looks similar to the following...
public class EntryForm: Form
{
public EntryForm()
{
}
private void EntryTextBox_KeyUp(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.Enter)
{
// do some stuff
Hide(); // I've also used DialogResult = DialogResult.OK here
e.Handled = true;
}
else if(e.KeyCode == Keys.Escape)
{
Hide(); // I've also used DialogResult = DialogResult.Cancel here
e.Handled = true;
}
}
}
I can 'hack' it and make the noise stop by adding the following code to the form's constructor.
AcceptButton = new Button();
CancelButton = new Button();
As I stated this causes the sound to not play, but I think this is bad form; especially since I don't need a button on the form.
Anyone know why this is the behavior and if there is a cleaner way to stop the error sound from playing?
In the KeyDown event, set e.Handled = true and e.SuppressKeyPress = true.
There's a more "correct" fix, one that works regardless of how many controls you have and follows the Windows Forms design model. Paste this code into your form:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
if (keyData == Keys.Escape || keyData == Keys.Enter) {
this.Hide();
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
This is too long a reply to Nobugz answer to fit in a comment. If you use Nobugz code as is :
the Form is going to be hidden no matter which control on the form is active and has keyboard input focus, and that is independent of whether the Form has the 'KeyPreview property set to 'true or 'false.
Here's what you need to do to make only a specific control (in this case a TextBox named 'textBox1) be hidden in the ProcessCmdKeys over-ride :
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (msg.HWnd == textBox1.Handle)
{
if (keyData == Keys.Escape || keyData == Keys.Enter)
{
textBox1.Hide();
return true;
}
}
return base.ProcessCmdKey(ref msg, keyData);
}
Of course if you wanted to handle the case of multiple controls needing to be hidden, you could implement a 'switch statement or whatever to test the msg.HWnd against : note I make the assumption here that all controls that could have keyboard input will have a valid HWnd.
Some memory (vague) of a situation in which I used this technique, and a text input control somehow still had keyboard input focus ... when I did not intend for it to ... makes me want to add an additional test like this :
&& this.ActiveControl == textBox1
But, take that with a "grain of salt" since I can't be certain it is necessary.