I am designing a custom calculator. Any key pressed on this calculator form should be captured at the 'Form' level. To this end, I've the following code-
private void BindControlMouseClicks(Control con)
{
con.MouseClick += delegate(object sender, MouseEventArgs e)
{
TriggerMouseClicked(sender, e);
};
// bind to controls already added
foreach (Control i in con.Controls)
{
BindControlMouseClicks(i);
}
// bind to controls added in the future
con.ControlAdded += delegate(object sender, ControlEventArgs e)
{
BindControlMouseClicks(e.Control);
};
}
private void TriggerMouseClicked(object sender, MouseEventArgs e)
{
}
private void Form1_Load(object sender, EventArgs e)
{
this.KeyPreview = true;
this.KeyPress +=new KeyPressEventHandler(Form1_KeyPress);
BindControlMouseClicks(this);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
}
void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
string key;
switch (e.KeyChar)
{
case '\r':
key = "ENTER";
break;
case ' ':
key = "SPACE";
break;
case (char)27:
key = "ESCAPE";
break;
default:
key = e.KeyChar.ToString();
break;
}
/* Some other code */
}
I've set breakpoints and added debug statements in the event handler function Form1_Keypress. Surprisingly all relevant keys ( Numerals, alphabets, Escape, Space etc ) hit the callback function except the ENTER key. This happens with the NUMPAD ENTER key too.
Any ideas why only the ENTER key is being handled differently?
EDIT
My form has a bunch of buttons and a textbox. When I place the focus on the textbox, voila, the callback is called for the ENTER key too! But if I put the focus on any of the buttons, no event is generated on ENTER key press. As I've set KeyPreview to true, the form must be getting this event irrespective of where the focus is, right?
EDIT 2
This happens only when there are buttons on the form and at least on of them has focus on it. If any other control has focus on it, it works just fine. I have not set AcceptButton attribute of the form.
As MSDN says(.NET TextBox - Handling the Enter Key), you can try use (char)Keys.Return instead of \r:
switch (e.KeyChar)
{
case (char)Keys.Return:
key = "ENTER";
break;
Also may be there is some button with AcceptsReturn property set to true on the form?
The problem I describe arises when any of the buttons on my form has focus. So I did these two things -
Set any_button.TabStop = false initially. This makes sure none of the buttons get focus when the form is launched
When we click a button with a mouse, it regains focus. And we end up in the same problem. To solve this, in the Mouse Click Handler, I just pass the focus from the button to some other control. For instance, my form had a menustrip and I just invoked, menustrip1.Focus() in the Mouse Click Handler.
Now, ENTER keypresses are caught in Form_Keypress handler.
This is a workaround. But I am yet to figure out why ENTER keypress is not caught by the form when the focus is on a button and not on other controls. I would be glad to have more answers for this Qn
Related
I have a WPF project. In this project at some point I'm dynamically making button in code behind like this:
private Button makeButton()
{
Button b = new Button();
b.Width = 24;
b.Height = 19;
b.Click += ButtonClick;
return b;
}
Where the ButtonClick is:
public void ButtonClick(object sender, RoutedEventArgs e)
{
// Do stuff...
}
Sometimes happen the event handler is called on pressing enter, even when button is not focused.
So my question is how can I disable to handle this event when it's caused by enter.
Tnaks you
I had the same problem. Using PreviewMouseLeftButtonUp event fixed my problem. It will not hire when you use enter button
It is probably getting focused before you press Enter.
Anyway, you could try to set the Focusable property to false:
b.Focusable = false;
Also make sure that you don't set the IsDefault property to true.
I'm not sure how this is happening with the button not focussed. Maybe this is logical rather than keyboard focus.
It'd have been nice to have a minimal reproduction.
Two things you can try.
1)
Eat the enter key just in case the keypress is somehow going to the button by using the previewkeydown event on the button. Marking the event as handled will stop the keydown event from firing so no enter will reach the button if it's somehow logically receiving the keypress.
b.PreviewKeyDown += (o, e) =>
{
if (e.Key == Key.Enter) e.Handled = true;
};
Set IsDefault="False" on the buttons in case they're somehow being set as default.
I have a user authentication form with username and password textboxes.There is an okay button that fires the code to validate the credentials.
I want the same code to get executed when the user hits Enter key anywhere on the form.
So i register for the keypress event like this
this.KeyPress += UserLogin_KeyPress;
private void UserLogin_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == (char)13)
{
MessageBox.Show("enter");
}
}
This event is not triggered at all.What i'm i doing wrong?
Try setting the property keypreview to true and changing to keydown instead since KeyPress don't support e.Keycode:
private void UserLogin_KeyPress(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
MessageBox.Show("Enter");
}
}
Try this:
private void UserLogin_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
MessageBox.Show("enter");
}
}
As mentioned, set form.KeyPreview = true so that most key events will be given to the form before the controls.
However, note that this doesn't always work, and some controls will still "steal" certain key presses anyway. For example, if a Button has focus, then an Enter keypress will be used by the button to activate it, before you get a chance to see it, and since it counts as having been "handled", you never get to see the keypress.
The workaround I use for this is to set focus to something that I know will not steal the enter key press, for key presses that occur leading up to the enter key press. So, if the pressed keys are <1><2><3><4><ENTER> then the 1-4 keys all set focus to something that is not a button (usually, the textbox where I am displaying the resulting text), and then when <ENTER> is pressed, it should make it to your form's event handler (as long as KeyPreview == true).
It's only looking at the form. Controls on the form also need to be wired in.
I am currently using Visual Studio, and I don't know if this is a glitch or not, but when I go into the form properties, and show the events, there are two events called KeyDown and KeyUp. Now when I do the same for a PictureBox, it has way less events and no KeyDown and KeyUp events. Does the PictureBox support less events then other things? Is this a glitch?
Screenshot of Form1 properties:
Screenshot of PictureBox1 properties:
As others here have stated, the most appropriate method for capturing keyboard event in this situation is to intercept key events at the Form level, as the PictureBox control is incapable of receiving focus and lacks exposed key events.
To accomplish this, first set the KeyPreview property of the form to true within the designer, or alternatively within the form's constructor:
this.KeyPreview = true;
Then, subscribe to the KeyUp event:
this.KeyUp += MainForm_KeyUp;
Finally, use an event handler similar to as follows to intercept and process key events:
private void MainForm_KeyUp(object sender, KeyEventArgs e)
{
switch (e.KeyCode)
{
case Keys.A:
// Perform some action...
break;
case Keys.B:
// Perform some action...
break;
case Keys.End:
// Perform some action...
break;
// etc...
}
}
If you intend to "consume" the key from within the event handler, you may set the Handled property of the KeyEventArgs object as follows:
e.Handled = true;
Its not a glitch. Its the way it is. You don't type in PictureBox.
If you need to do some task through keys, route it through form only
You can use a simple trick to handle keyboard events with PictureBox.
Add an handler for MouseEnter and MouseLeave events so to set focus to the PictureBox when the cursor is over. Doing so it will catch keyboard events.
...
_myPictureBox.MouseEnter += new EventHandler(myPictureBox_MouseEnter);
_myPictureBox.MouseLeave += new EventHandler(myPictureBox_MouseLeave);
_myPictureBox.KeyDown += new KeyEventHandler(myPictureBox_event_KeyDown);
...
private void myPictureBox_MouseEnter(object sender, EventArgs e)
{
Focus();
}
private void myPictureBox_MouseLeave(object sender, EventArgs e)
{
FindForm().ActiveControl = null;
}
private void myPictureBox_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Delete)
MessageBox.Show("Bye");
}
The PictureBox is used to display images and therefore has no need for keyboard input. It does not take the focus and does not interact with the keyboard.
Event handlers for KeyDown, KeyPress and KeyUp can be added to a PictureBox. For example, in Visual Basic, for a PictureBox called MyPicBox, add a handler for MyPicBox.MouseEnter and put the line MyPicBox.Select() in the handler.
The picture box will now respond to keyboard events. For example, suppose the picture box is showing a visual display of a scientific image. Key combos like Shift-Ctrl-H or Shift-Ctrl-V can be intercepted by a PictureBox.KeyDown handler to invoke some cursor position dependent action such as displaying a cut through the underlying array:
Private Sub MyPicBox_KeyDown(sender As Object, e As KeyEventArgs) Handles MyPicBox.KeyDown
If e.Control AndAlso e.Shift Then
Select Case e.KeyCode
Case Keys.V
MyCut = Cut.VERTICAL
Exit Select
Case Keys.H
MyCut = Cut.HORIZONTAL
Exit Select
Case Keys.N
MyCut = Cut.NONE
Exit Select
End Select
End If
End Sub
The keyboard events are listed at https://learn.microsoft.com/en-us/dotnet/api/system.windows.forms.picturebox
I have a button for which I set the KeyPress event.
this.myButton.KeyPress += new KeyPressEventHandler(this.myButtonEvent_keypress);
private void myButtonEvent_keypress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == (char)Keys.Return || e.KeyChar == (char)Keys.Space)
{
// do something
}
}
Now whenever the Space key is pressed, I get the event triggered. This part works fine.
But for some reason, the Enter key press is not triggering the KeyPress
event. Also Alt, Ctrl, Shift are not working.
How can I make the button receive Enter key press?
UPDATE:
I tried below too without any luck
this.myButton.MouseClick += new MouseEventHandler(myButton_Click);
When a Button has focus and you press Enter or Space the Click event raises.
So to handle Enter or Space it's enough to handle Click event and put the logic you need there.
So you just need to use button1.Click += button1_Click;
private void button1_Click(object sender, EventArgs e)
{
MessageBox.Show("Clicked!");
}
If you really want to know if Enter or Space was pressed, you can hanlde PreviewKeyDown event:
private void button1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
if(e.KeyCode== Keys.Enter)
{
MessageBox.Show("Enter");
}
if (e.KeyCode == Keys.Space)
{
MessageBox.Show("Space");
}
}
Enter and space can be handled using click event.
this.myButton.Click += new EventHandler(myButton_Click);
The Button control in WinForms will eat Enter, Space, Tab, ESC, and a few other special key's press events. One method to intercept these events is to override Control.ProcessDialogKey. Or you can override IsDialogKey to say if a key should be handled as a special case.
A another option is to set KeyPreview = true on you parent Form. Then you can handle all KeyPress events at the Form level and use Form.ActiveControl if you need to see what control has Focus
I have a listbox which displays the contents of an array. The array is populated with a list of results when my "go" button is pressed.
The go button is set as the AcceptButton on the form properties so pressing the Enter key anywhere in the focus of the form re-runs the go button process.
Double clicking on a result from the array within the listbox works fine using below:
void ListBox1_DoubleClick(object sender, EventArgs e) {}
I would like to be able to use my arrow keys and enter keys to select and run an event without having to double click on the line within the listbox. (however go button runs each time instead)
Basically open the form, type search string, press enter to run go button, use up and down arrows then press enter on selection to run same event as double click above. Will need to change focus after each bit.
You can handle the KeyDown events for the controls you want to override. For example,
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
//execute go button method
GoButtonMethod();
//or if it's an event handler (should be a method)
GoButton_Click(null,null);
}
}
That will perform the search. You can then focus your listbox
myListBox.Focus();
//you might need to select one value to allow arrow keys
myListBox.SelectedIndex = 0;
You can handle the Enter button in the ListBox the same way as the TextBox above and call the DoubleClick event.
This problem is similar to -
Pressing Enter Key will Add the Selected Item From ListBox to RichTextBox
Certain controls do not recognize some keys when they are pressed in Control::KeyDown event. For e.g. list box does not recognize if the key pressed is Enter key.
See the remarks section of the Control::KeyDown event reference.
One way to resolve your problem might be writing a method for the Control::PreviewKeyDown event for your list box control:
private void listBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Up && this.listBox1.SelectedIndex - 1 > -1)
{
//listBox1.SelectedIndex--;
}
if (e.KeyCode == Keys.Down && this.listBox1.SelectedIndex + 1 < this.listBox1.Items.Count)
{
//listBox1.SelectedIndex++;
}
if (e.KeyCode == Keys.Enter)
{
//Do your task here :)
}
}
private void listBox1_PreviewKeyDown(object sender, PreviewKeyDownEventArgs e)
{
switch (e.KeyCode)
{
case Keys.Enter:
e.IsInputKey = true;
break;
}
}