KeyPreview (KeyUp) handler passing KeyUp to forms created in the method - c#

Issue
Weird problem. We've got two forms: the main application window and a settings form. The main form has its KeyPreview set to true, and a method attached to its KeyUp event. This is so that the settings window can be opened with a key shortcut (ctrl-m):
private void MyShortcuts(object sender, KeyEventArgs e)
{
if (e.Control && e.KeyCode == Keys.M)
{
e.Handled = true;
e.SuppressKeyPress = true;
MySettings sett = new MySettings();
sett.Show();
}
}
Now, that bit works just fine. However, the problem is that despite setting the Handled and SuppressKeyPress properties to true, the KeyUp event is still passed on to the MySettings form. I've traced this to ControlNativeWindow.OnMessage receiving what seems to be a different event (its Handled and SuppressKeyPress properties are set to false), and passing that on to the form and its focused control.
Questions
First of all, why is the event passed on despite instructing .Net not to do so?
Secondly, how do I prevent the event from firing?
Any ideas will be much appreciated, I run out of them myself.

What's happening here is that the M and the CTRL key are raising two separate KeyUp events (which is normal behavior). When you press CTRL and then M and then lift your finger off of the M key, a KeyUp event is raised, which your handler on the main form catches and uses to show the settings form. You then take your finger off of the CTRL key, which raises another KeyUp event (this time on the settings form, which is now the active form).
On the settings form, you can just check e.Control and ignore the event if it's true.

Instead of the KeyUp Event you should use the KeyDown event.
If you take a look at the documentation you'll see, that before the KeyUp event a KeyPress event will be thrown and this will be catched by your settings form.

Related

keyUp event not working [WinForm]

I have got some controls on the Panel and I am trying to delete them using "Delete" button. I handled KeyPress Event as mentioned in How to get Keypress event in Windows Panel control
Your issue is that the event MainForm_KeyUp does not even get fired on your key up, because you have focues another control. But you can fix that with KeyPreview.
A Form object has the property KeyPreview. According to the MSDN:
Gets or sets a value indicating whether the form will receive key events before the event is passed to the control that has focus.
So when you set:
this.KeyPreview = true;
You enable that your MainForm gets notified about those key events always. Even when any other Control is focused. So you enable that those key events will invoke MainForm_KeyUp().
Now set a breakpoint:
private void MainForm_KeyUp(object sender, KeyEventArgs e)
{
//set a breakpoint here, so you get confirmation, that the event will get fired
//on key up of the *delete* button
//...now do what you desire
}

How to fire both Shortcut Keys and KeyDown event? (C# Windows Form)

I have a TextBox's KeyDown event that start a timer when it is called. I also have a Paste MenuStripItem and I set the ShorcutKeys property in Design View to Ctrl + V.
I notice that when user press the shortcut keys (Ctrl + V), the KeyDown event will not be called. And when I set the ShortcutKeys property to None, KeyDown is normally called. Is there a way to fire both event when I press the Ctrl + V?
I has tried with other MenuStripItem and the result are the same.
EDIT: Thank you very much, #Hans. When I move my code from KeyDown event to ProcessCmdKey, it works really well. (So I suppose the ProcessCmdKey is the method which is called everytime a key is pressed nomatter what it is). Because you deleted your previous anwser so I can't mark it as answer now.
private void somethind_KeyDown(object sender, KeyEventArgs e)
{
if (KeyCodes.Contains(e.KeyValue) || (e.KeyCode==Keys.V && e.Control))
e.SuppressKeyPress = false;
else
e.SuppressKeyPress=true;
}
See this list of keycodes: http://www.cambiaresearch.com/articles/15/javascript-char-codes-key-codes
I hope this helps!

Overriding keypress

I know this may be an easy answer to some of you but i dont know how to properly do this. Ive created a text editor, that also has a docking window that will display functions. I have it set up in the menu that F8 is the shortcut key for showing the function window. I would also like to catch the F8 keypress event to parse the current data for the functions in the program but I cant get this to happen..
Capture your Text Editors KeyPressed Event and check the KeyEventArgs that are coming in, then mark the not handled as false which will cause the event to be passed up to the parent control:
Example
KeyPressed(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.F8) DoSomething();
e.Handled = false;
}
In response to the comment that you added to your question. You may need to set the controls KeyPreview to True. I think that KeyPreview may be available at only the form level, but I'm not sure.
Set up an event handler for the OnKeyPress (or OnKeyDown or OnKeyUp) event, and check which key was pressed (it will be in the event arguments). Then, you can do whatever you want.
I don't think the tagged answer is correct. The KeyPress event handler won't handle the Function keys; you need to use KeyUp event handler or ProcessDialogKey method.
I'm not sure to understand everything, but can't you use the KeyPress Event available in any Control ?

.NET: TextChanged event for TextBox not always firing, even though KeyUp and KeyDown are firing

I'm running into a very peculiar issue. I noticed that occasionally while typing into my TextBox, I'll lose some keystrokes. I added a bunch of trace statements in events hooked by this TextBox, and I found that when I lost keystrokes, the KeyUp, KeyDown, and KeyPress events all correctly fired, but the TextChanged event never fired.
Does anybody have any idea why this would happen? I could write this off as a ".NET bug", but I'd rather figure out if there is a solution here.
In case there is a suggestion that I use the KeyUp/KeyDown events to determine if the text has changed, there is an issue there as well. KeyUp/KeyDown are called multiple times for each key press, so it would be very difficult to determine if someone was typing the same letter multiple times.
Hmmm....
This is going to be a shot, but, you did say you have the KeyUp, KeyDown and KeyPress event handlers right? Have you set the flag e.Handled to true in the event handlers, have a look here:
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
e.Handled = true;
}
private void textBox1_KeyUp(object sender, KeyEventArgs e)
{
e.Handled = true;
}
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
e.Handled = true;
}
Have a look here in the MSDN about this Handled property. (If you have MSDN 2008 SP 1 installed locally, the link is ms-help://MS.MSDNQTR.v90.en/fxref_system.windows.forms/html/dfc80b44-1d79-6315-cbea-1388a048c018.htm)
To quote:
Handled is implemented differently by different controls within Windows Forms.
For controls like TextBox which subclass native Win32 controls, it is
interpreted to mean that the key message should not be passed to the underlying
native control.
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.
Maybe it is not set i.e. e.Handled = false; thereby preventing the TextChanged Event from firing?
Can you check and confirm this?
Edit: After dreadprivateryan's response, I can suspect (due to lack of code posted), based on his response, e.Handled is true for when Enter key is pressed and false for everything else which in my mind, thinks that is the reason why no further keystrokes are being accepted as a result of this.
Are you trying to set focus to another control upon the Enter key being pressed? It could be that both KeyUp and KeyDown are conflicting...
Remove the keyboard hook and disable it...
My suggestion is to change the code completely in this manner as shown, take out either KeyDown or KeyUp Event Handler as they, simplistically put it, are the same, ok, technically, it is designated respectively for when a key is pressed down, and likewise when a key is released. Have a look at this link here. There was a similar question posted here on SO.
In the example below, I used the keyUp event handler to switch focus to the next available control upon enter key being pressed. In the KeyPress event handler, this simply filters the input and only allows numbers 0-9 respectively, anything else gets discarded. Included in that event handler, is the allowance for the backspace key to provide editing.
private void textBox1_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter) SendKeys.Send("{TAB}");
}
private const string VALID_KEYS = "0123456789";
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (VALID_KEYS.IndexOf(char.ToUpper(e.KeyChar)) != -1 || e.KeyChar == (char)8)
e.Handled = false;
else
e.Handled = true;
}
Hope this helps,
Best regards,
Tom.
I don't actually know, but I have a random guess: You running in a VM?
One hack you could use is make a timer that reads the text and compares to the previously entered value. Call the event handler code when it isn't equal to the previously checked value. When you need to use the final entered value, do one additional check, in case the timer hasn't fired yet.
Do you mean the keypress is actually lost and never shows up in the box? Or do you mean you don't get a TextChanged event for every keypress?
I believe the TextChanged event is driven by the operating system's EN_CHANGE notification which is sent via a WM_COMMAND message. I know that certain kinds of messages in Windows are "coalesced" to avoid redundant notifications. For example this can happen with WM_MOUSEMOVE messages and is why you don't receive a mouse move event for every pixel that the mouse moves across the screen.
I can't say for sure but I suspect that the TextChanged event behaves this way as well. I can say though that alternate input methods have this side effect too. When using a Tablet PC input panel, the textbox will not get a TextChanged notification for every character.

Winform keyboard management

I would like to control the focus of my winform application. It is made of a custom listbox and several other component.
I want all the keyboard event be managed by my window handlers in order to avoid specific control key handling (for example when I press a character and the list box is focused, the item starting with the correspondant letter is selected which is not a correct behaviour for my application).
How can I achieve this?
Make sure your form's KeyPreview property is set to true. Then this code should work for canceling your key events to the listbox...
private void Form1_KeyPress(object sender, KeyPressEventArgs e)
{
if (this.ActiveControl == listBox1)
e.Handled = true;
}
The KeyPress event may not work for all your scenarios. In that case, I would try out the KeyDown event.

Categories