I want to have the Esc key undo any changes to a textbox since it got focus.
I have the text, but can't seem to figure out how to capture the Esc key. Both KeyUp and KeyPressed don't seem to get it.
This should work. How are you handling the event?
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Escape)
{
MessageBox.Show("Escape Pressed");
}
}
Edit in reply to comment - Try overriding ProcessCmdKey instead:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == Keys.Escape && myTextBox.Focused)
{
MessageBox.Show("Escape Pressed");
}
return base.ProcessCmdKey(ref msg, keyData);
}
is this what you're looking for?
string origStr = String.Empty;
private void txtOrig_Enter(object sender, EventArgs e)
{
origStr = txtOrig.Text;
}
private void txtOrig_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == Convert.ToChar(Keys.Escape))
{
txtOrig.Text = origStr;
}
}
Supposedly some keys are not considered "input keys" and so are not listened to by default. You need to handle PreviewKeyDown first to enable it.
myTextBox.PreviewKeyDown += (s, e) => {
if (e.KeyCode == Keys.Escape) {
e.IsInputKey = true;
Debug.Print("ESC should get handled now.");
}
};
However, results from testing say otherwise, so it may depend on framework version. For me, whether I do that or not, KeyDown does not get called for ESC, and whether I do that or not, KeyPress DOES get called for ESC. This is while a TextBox has focus, so it may also depend on the control.
Related
I need an application that can detect the keypress of F13-F24. I tried making a form and setting keydown and Keypress events and printing in a messagebox the key pressed but when i press F13-F24, i don't get a messagebox
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
MessageBox.Show(e.KeyCode.ToString());
}
private void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
MessageBox.Show(e.KeyChar.ToString());
}
This didn't seem to work. How can I do this?
You can capture this using System.Windows.Forms.KeyEventHandler.
The KeyEventHandler will provide a KeyEventArgs object that includes a KeyCode property. KeyCode is a System.Windows.Forms.Keys enumeration and supports F1-F24.
private void KeyDownHandler(object sender, System.Windows.Forms.KeyEventArgs e) {
if (e.KeyCode == Keys.F13) {
//F13
} else if (e.KeyCode == Keys.F14) {
//F14
} else if (e.KeyCode == Keys.F15) {
//F15
}
// etc
}
If you don't have a keyboard capable of sending higher F-keys, the F13-F24 keys are the equivilent of SHIFT-F1-SHIFT-F12. You can capture this sequence using the KeyCode and Modifiers (Modifiers == Keys.Shift) properties together.
Windows 10 doesn't recognize the higher Function keys 13-24. You can test this by turning on the Windows Narrator functionality, and then press Shift -F1. The narrator just says "Shift F1", not "F13"
So, instead I recommend that you just detect Shift -F1 to Shift -F12 instead.
private void Form1_PreviewKeyDown(object sender, KeyPressEventArgs e)
{
if(e.KeyCode == Keys.F1 && e.Modifiers == Keys.Shift)
{
MessageBox.Show("Shift-F1 pressed");
}
}
As MstfAsan commented, you need to use the PreviewKeyDown eventhandler and set the form's KeyPreview property to True for this to work
I currently have the following event handler which catches the Ctrl+Enter key combo in my Form code:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter && e.Control)
{
// Stuff
}
}
I also have two non-ReadOnly TextBoxes in the form, one of which is multiline, while the other one isn't. Whenever I hit Ctrl+Enter, the event does get handled, but it also registers as an Enter keypress when the focus is in either TextBox. What I want to do is register the key combo without the Enter keypress modifying the text in either box. Is there any way I could go about doing this?
Your best choice is use ProcessCmdKey: Just add this to your Form add it will work:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == (Keys.Control | Keys.Enter))
{
// Stuff
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
You should use the PreviewKeyDown event instead and set the IsInputKey property accordingly:
private void Form1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
if (e.KeyCode == Keys.Enter && e.Control)
{
// Stuff
e.IsInputKey = false;
}
}
UPDATE: From the name of your handler, I guess you added it to the Form's KeyPress/KeyDown/PreviewKeyDown event. Instead you should register the method I showed above with each TextBox's PreviewKeyDown event.
To not destroy what already works for you, you may leave your code as it is and just add a handler to the TextBox's PreviewKeyDown event where you set IsInputKey to false for the specified keys, but don't do your // Stuff.
This is not a duplicate. Many similar threads discuss capturing a combination involving a modifier key.
I need to get something triggered when a shortcut key (a combination of Insert+Tab) is pressed from a control, say Button.
Catch:
This involves no modifier key like Alt or Shift for which .NET has built in checking.
This has Tab key which is not caught so easily.
What I tried and came close:
1) KeyDown Event but doesnt capture Tabs..
[DllImport("user32.dll")]
public static extern int GetKeyboardState(byte[] keystate);
static void form_KeyDown(object sender, KeyEventArgs e)
{
if (!(((Form)sender).ActiveControl is Button))
return;
byte[] keys = new byte[255];
GetKeyboardState(keys);
if (keys[(int)Keys.Insert] == 129 && keys[(int)Keys.Tab] == 129)
{
// doesn't work
}
if (keys[(int)Keys.Insert] == 129 && keys[(int)Keys.J] == 129)
{
// works, since here this doesnt involve Tab
}
}
This works with regular combinations, doesnt fire along with Tab.
2) KeyPreview Event which captures Tab key, but I do not know how to get a combination of keys pressed
static void form_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
if (!(((Form)sender).ActiveControl is Button))
return;
if (e.KeyCode == Keys.Tab)
//works
if (e.KeyCode == Keys.Insert && e.KeyCode == Keys.Tab)
//doesn't hit.
}
Requirement:
1) I am not registering the event from Form class. Instead I have a utility class which creates all required events (along with other shortcuts). I just pass the instance of form to a static function. So I am quite unsure how I should utilize the various key overriding calls. Here is how I do it:
public frmLogin()
{
InitializeComponent();
Utility.SetFormEvents(this);
}
static void SetFormEvents(Form f){
//foreach control...........
}
But I can give up on this..
Thanks..
Tab is considered a command key, you don't actually get notified of it being pressed directly. You could PInvoke the GetKeyState method, but I think it's just easier to recognize that tab is a command key (and override ProcessCmdKey) and keep track of whether the Insert key is up or down. For example:
static bool insertPressed;
static bool tabPressed;
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if(keyData == Keys.Tab)
{
tabPressed = true;
CheckForTabAndInsert();
}
return base.ProcessCmdKey(ref msg, keyData);
}
static void form_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Insert)
{
insertPressed = true;
CheckForTabAndInsert();
insertPressed = false;
}
}
static void form_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Insert) insertPressed = false;
}
The drawback is that you only really get a KeyPress for tab with ProcessCmdKey, so you can only really support Insert+Tab (not Tab+Insert). This is because Tab is used to switch context from one control to another. Depending on your situation (i.e. in the context of a text box), you could make use of the AcceptTab property to possibly just use KeyUp and KeyDown... But, from what you posted, that doesn't appear to be the case.
Basically, I want to be able to trigger an event when the ENTER key is pressed. I tried this already:
private void input_KeyDown(object sender, KeyEventArgs e)
{
if (e.Equals("{ENTER}"))
{
MessageBox.Show("Pressed enter.");
}
}
But the MessageBox never shows up. How can I do this?
Give this a shot...
private void input_KeyDown(object sender, KeyEventArgs e)
{
if(e.KeyData == Keys.Enter)
{
MessageBox.Show("Pressed enter.");
}
}
To add to #Willy David Jr answer: you also can use actual Key codes.
private void input_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyChar == 13)
{
MessageBox.Show("Pressed enter.");
}
}
You can actually just say
private void input_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
MessageBox.Show("Pressed enter.");
}
}
You can use the Keypress event. If you are just looking for the "Enter" keypress, then you probably don't care about modifier keys (such as Shift and/or Ctrl), which is why most would use KeyDown instead of Keypress. A second benefit is to answer the question that is almost always asked after implementing any of the other answers: "When I use the referenced code, why does pressing "Enter" cause a beep?" It is because the Keypress event needs to be handled. By using Keypress, you solve both in one place:
private void input_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == (char)Keys.Enter)
{
// Your logic here....
e.Handled = true; //Handle the Keypress event (suppress the Beep)
}
}
If your Form has AcceptButton defined, you won't be able to use KeyDown to capture the Enter.
What you should do is to catch it at the Form level. Add this code to the Form:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if ((this.ActiveControl == myTextBox) && (keyData == Keys.Return))
{
//do something
return true;
}
else
{
return base.ProcessCmdKey(ref msg, keyData);
}
}
You can also do this:
private void input_KeyDown(object sender, KeyEventArgs e)
{
if(e.KeyCode== Keys.Enter)
{
//Your business logic here.
}
}
The only difference with KeyCode vs KeyData is that KeyCode can detect modifiers combination with KeyCode (e.g. CTRL, Shift + A) which you don't need here.
Fast forward 2022, the following statement above is completely other way around.
"The only difference with KeyCode vs KeyData is that KeyCode can detect modifiers combination with KeyCode (e.g. CTRL, Shift + A) which you don't need here."
the KeyDown event e.KeyCode does not trigger Keys.Enter
DataGridView keydown event is not working when I am editing text inside a cell.
I am assigning shortcut Alt+S to save the data, it works when cell is not in edit mode, but if it is in edit mode below code is not working
private void dataGridView1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyData == (Keys.Alt | Keys.S))
{
//save data
}
}
Whenever a cell is in edit mode, its hosted control is receiving the KeyDown event instead of the parent DataGridView that contains it. That's why your keyboard shortcut is working whenever a cell is not in edit mode (even if it is selected), because your DataGridView control itself receives the KeyDown event. However, when you are in edit mode, the edit control contained by the cell is receiving the event, and nothing happens because it doesn't have your custom handler routine attached to it.
I have spent way too much time tweaking the standard DataGridView control to handle edit commits the way I want it to, and I found that the easiest way to get around this phenomenon is by subclassing the existing DataGridView control and overriding its ProcessCmdKey function. Whatever custom code that you put in here will run whenever a key is pressed on top of the DataGridView, regardless of whether or not it is in edit mode.
For example, you could do something like this:
class MyDataGridView : System.Windows.Forms.DataGridView
{
protected override bool ProcessCmdKey(ref System.Windows.Forms.Message msg, System.Windows.Forms.Keys keyData)
{
MessageBox.Show("Key Press Detected");
if ((keyData == (Keys.Alt | Keys.S)))
{
//Save data
}
return base.ProcessCmdKey(ref msg, keyData);
}
}
Also see related, though somewhat older, article: How to trap keystrokes in controls by using Visual C#
Another way of doing it is by using the EditingControlShowing event to redirect the event handling to a custom event handler as below:
private void dataGridView1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
if (e.Control is DataGridViewTextBoxEditingControl tb)
{
tb.KeyDown -= dataGridView1_KeyDown;
tb.KeyDown += dataGridView1_KeyDown;
}
}
//then in your keydown event handler, execute your code
private void dataGridView1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyData == (Keys.Alt | Keys.S))
{
//save data
}
}
This is true that EditingControlShowing can help, but not if you wants to catch the Enter key. In that case, one should use the following method:
private void dataGridView_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
if (e.Control is DataGridViewTextBoxEditingControl)
{
DataGridViewTextBoxEditingControl tb = e.Control as DataGridViewTextBoxEditingControl;
tb.KeyDown -= dataGridView_KeyDown;
tb.PreviewKeyDown -= dataGridView_PreviewKeyDown;
tb.KeyDown += dataGridView_KeyDown;
tb.PreviewKeyDown += dataGridView_PreviewKeyDown;
}
}
void dataGridView_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
if (e.KeyData == Keys.Enter)
{
<your logic goes here>
}
}
A simpler way I just tried out is as follows:
Set the KeyPreview property of the Form to true.
Instead of catching the KeyDown event on Grid, catch the KeyDown event on Form.
Code as follows:
Private Sub form1_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
If grd.Focused Then
'Do your work
End If
End Sub
I worked with this
private void grdViewOrderDetail_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
grdViewOrderDetail_KeyDown(null,null);
}
private void grdViewOrderDetail_KeyDown(object sender, KeyEventArgs e)
{
//Code
}
The solution
class MyDataGridView : System.Windows.Forms.DataGridView {
protected override bool ProcessCmdKey(ref System.Windows.Forms.Message msg, System.Windows.Forms.Keys keyData) {
if ( keyData == Keys.Enter ) {
.
Process Enter Key
.
}
return base.ProcessCmdKey(ref msg, keyData);
}
}
Worked perfectly for me
use PreviewKeyDown event
private void dataGridView1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
}