It seems that the keydown event does not handle spacebar presses unless the control has focus. How do I, though?
I am using c# and I am making a windows store app, if it matters.
I'm not sure of what code you have within your project already but I'd recommend some JQuery along the lines of:
$(window).keypress(function(e) {
if (e.keyCode == 0) {
console.log('Space pressed, here is my event');
}
});
As the event is bound to a Window event, it will find it regardless of whether an input field is focused or not.
I figured it out.
Window.Current.CoreWindow.KeyDown += CoreWindow_KeyDown;
captures all key events.
Related
I have a TextBox. After leaving the textBox the first character should be a capital Letter.
Three Events work as same. They are Leave,Validating and Validated.
if (txtLocl.Text.Length > 0)
txtLocl.Text = txtLocl.Text.Substring(0, 1).ToUpper() + txtLocl.Text.Substring(1);
Which event of these 3 events should I use?
You can subscribe to the Control.Leave event which will be fired when the control loses focus. Originally, I thought using Control.LostFocus would be the most appropriate event to use but it is not available via the designer meaning you would need to manually subscribe to the event which is a bit ugly and unconventional in my opinion.
private void inputTextBox_Leave(object sender, EventArgs e)
{
if (inputTextBox.Text != string.Empty)
{
string input = inputTextBox.Text;
inputTextBox.Text = input.First().ToString(CultureInfo.InvariantCulture).ToUpper() +
string.Join(string.Empty, input.Skip(1));
}
}
You sound like you're interested in Control.Validating. The advantage of using Control.Validating is that you can utilize the event handler's given argument; CancelEventArgs and set the Cancel property to true. What this will do is stop the control from losing focus and forcing the user to enter a valid value. I don't think this is appropriate for your application as you are not really validating anything but formatting the input.
private void inputTextBox_Validating(object sender, CancelEventArgs e)
{
if (inputTextBox.Text == string.Empty)
{
statusLabel.Text = "The given input is not valid.";
e.Cancel = true;
}
}
Bear in mind that when the form closes, all controls subsequently lose focus and the Control.Validating event is fired which could stop the Form closing until all fields pass their relative validation checks. If you find yourself needing to avoid this behavior a quick search will prevail.
There are many other events also available.
As said by MSDN, When you change the focus by using the keyboard (TAB, SHIFT+TAB, and so on), by calling the Select or SelectNextControl methods, or by setting the ContainerControl.ActiveControl property to the current form, focus events occur in the following order:
1) Enter
2) GotFocus
3) Leave
4) Validating
5) Validated
6) LostFocus
When you change the focus by using the mouse or by calling the Focus method, focus events occur in the following order:
1) Enter
2) GotFocus
3) LostFocus
4) Leave
5) Validating
6) Validated
If the CausesValidation property is set to false, the Validating and Validated events are suppressed.
textBox1_Leave is appropriate for you.
Check the events and description about textboxes over here>>
http://msdn.microsoft.com/en-us/library/system.windows.forms.textbox_events.aspx
Hope its helpful.
You might want to subscribe to LostKeyboardFocus event (in WPF) or Leave event (in WF).
I'd suggest using the Leave because I assume you aren't validating the value, but formatting it. Validating and Validated should contain code for validation and the aftermath of validation respectively, IMO.
I have a custom search activity that serves search suggestions. I get a reference to the search input box and set a handler:
mSearchInput = FindViewById(Resource.Id.searchBoxInput) as EditText;
mSearchInput.KeyPress += new System.EventHandler<View.KeyEventArgs>(OnSearchKeypress);
This is the handler that should be called on every key press:
private void OnSearchKeypress(object sender, View.KeyEventArgs e) {
string query = mSearchInput.Text;
if (e.KeyCode == Keycode.Enter && !string.IsNullOrEmpty(query)) {
e.Handled = true;
// launch search results activity
}
else {
e.Handled = false;
if (query.Length > 2) {
// load suggestions if we have 2+ characters
}
}
}
For some reason, on the soft keyboard, only certain key presses fire the event at all. Enter and Delete fire the event. Alphanumeric keys do not. Even if I take out all of the logic and simply do a Toast with e.KeyCode.ToString() it only shows the toast on those few keys.
Am I listening for the wrong event, is this a bug, or have I made some other mistake?
Device: Droid X2
Mono Version: 4.0.4
Update: I discovered that KeyPress is triggered twice for each physical press of a key: once for KeyEventActions.Up and once for Down. This doesn't explain why only certain keys fire the event but it should be noted that you need to check event.E.Action to find out whether the press or release is currently triggering the event.
When is the event not firing? If it is when the user is typing, then you can use the TextChanged event. You can then continue with your implementation in the OnKey method.
Also, look at this article for the "search" button:
http://www.stackoverflow.com/questions/1489852/android-handle-enter-in-an-edittext
I've tried using the KeyUp and KeyDown events to read keyboard input but as soon as I place other controls on the Winform, the keys are not read. How do I make sure that the keys are read?
You could set KeyPreview = true on your form to catch keyboard events.
EDITED to let you understand:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.A)
e.SuppressKeyPress = true;
}
Stupid sample that receives keyboard events and drop if A was pressed.
If focus is in a textbox, you'll see that text is written, but not A!!
EDITED AGAIN: I took this code from a VB.NET example.
In your usercontrol, use the text box's "Keypress" event to raise a "usercontrol event".
This code would be in your custom usercontrol:
'Declare the event
Event KeyPress(KeyAscii As Integer)
Private Sub Text1_KeyPress(KeyAscii As Integer)
RaiseEvent KeyPress(KeyAscii)
End Sub
See: http://msdn.microsoft.com/en-us/library/system.windows.forms.form.keypreview.aspx
set KeyPreview = true and your KeyUp and KeyDown will recognize all keyboard input.
As marco says set KeyPreview to true on your form to catch the key events in the entire form rather than just a control.
Use the KeyPress event ... KeyUp/Down are more for the framework than your code. KeyDown is good if you want to disable a key ... numeric only fields etc. In general KeyPress is the one you're after.
If you want to prevent the keystrokes from propogating to other controls set KeyPressEventArgs.Handled = true.
http://msdn.microsoft.com/en-us/library/system.windows.forms.control.keypress(v=VS.90).aspx
Have you wired up the event handler?
MyForm.KeyDown += MyHandler;
You can also do this in the properties pane ... click the event icon ...
If you are looking for your Form itself to read the keyboard input, you already have your answer from other correspondents. I am adding this contribution for the possibility that you might want to add key handling to other controls or user controls on your form. My article Exploring Secrets of .NET Keystroke Handling published on DevX.com (alas, it does require a registration but it is free) gives you a comprehensive discussion on how and why all the various keyhandling hooks and events come into play. Furthermore, the article includes a "Keystroke Sandbox" utility for free download that actually lets you see which controls are receiving which key handling events.
Here is one illustration from the article to whet your appetite:
I am attempting to simulate several keyboard actions in a wpf textbox, including arrow presses (to move caret etc) from another event (e.g. a button click). I have no problem with adding text by raising the
TextCompositionManager.TextInputEvent
event, but attempting to send keys through Keyboard events is not working:
Keyboard.Focus(targetTextBox);
KeyEventArgs ke = new KeyEventArgs(Keyboard.PrimaryDevice, PresentationSource.FromVisual(targetTextBox), 0, Key.UP);
ke.RoutedEvent = Keyboard.KeyDownEvent;
targetTextBox.RaiseEvent(ke);
Is there a way to send control keys through the TextInputEvent, or making the Keyboard event work - i have tried using previewDownEvent and pairing with keyUp events.
EDIT: Also i would prefer to do this through wpf if possible, without using windows forms.
Thanks
I believe this is what you're looking for, though it doesn't use events.
...
SendKeys.Send("{LEFT}");
SendKeys.Send("{RIGHT}");
...
Remember to set focus to the control you want to input in first.
I've been working for a while on my Windows Forms project, and I decided to experiment with keyboard shortcuts. After a bit of reading, I figured I had to just write an event handler and bind it to the form's KeyDown event:
private void Form1_KeyDown(object sender, KeyEventArgs e)
{
if (e.Control && e.Alt && e.KeyCode == Keys.O)
{
MessageBox.Show("Ctrl+Alt+O: magic!");
}
}
I did that the good ol' way of opening the Properties panel of the Visual Studio designer, then double-clicking on the KeyDown event of my form to generate the Form1_KeyDown event handler. But on testing my application, the form doesn't respond at all to the Ctrl+Alt+O keyboard shortcut. The Visual Studio designer did generate the code to bind the event handler to the form though:
private void InitializeComponent()
{
// ...
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.Form1_KeyDown);
// ...
}
So I tried adding a Console.WriteLine() call to the handler to check that it was being called at all, but no luck on that either.
Also, I tried to set a breakpoint on the event binding call (shown just above) and found that the program reaches that breakpoint just fine. But any breakpoints I set within the method definition itself are never reached.
To make sure I was doing the first few steps correctly, I tried repeating them with:
A new form in the same solution.
Same issue: the form doesn't respond when I press my Ctrl+Alt+O keyboard shortcut and the debugger isn't even stepping into the event handler. Tried this again and it works.
A brand new WinForms solution.
It works perfectly: the message dialog appears (the Console.WriteLine() call also works).
So I'm quite lost here. What's preventing all the forms in this one project from receiving KeyDown events?
Does your form have KeyPreview property set to true?
Form.KeyPreview Property
Gets or sets a value indicating whether the form will receive key
events before the event is passed to the control that has focus.
http://msdn.microsoft.com/en-us/library/system.windows.forms.form.keypreview.aspx
The most common piece of advice for this problem on StackOverflow and the MSDN1, 2 (including the accepted answer here) is quick and easy:
KeyDown events are triggered on a Form as long as its KeyPreview property is set to true
That's adequate for most purposes, but it's risky for two reasons:
KeyDown handlers do not see all keys. Specifically, "you can't see the kind of keystrokes that are used for navigation. Like the cursor keys and Tab, Escape and Enter for a dialog."
There are a few different ways to intercept key events, and they all happen in sequence. KeyDown is handled last. Hence, KeyPreview isn't much of a preview, and the event could be silenced at a few stops on the way.
(Credit to #HansPassant for those points.)
Instead, override ProcessCmdKey in your Form:
protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
if (keyData == Keys.Up)
{
// Handle key at form level.
// Do not send event to focused control by returning true.
return true;
}
return base.ProcessCmdKey(ref msg, keyData);
}
That way, all keys are visible to the method, and the method is first in line to see the event.
Note that you still have control over whether or not focused controls see the KeyDown event. Just return true to block the subsequent KeyDown event, rather than setting KeyPressEventArgs.Handled to true as you would in a KeyDown event handler. Here is an article with more details.
Try setting the KeyPreview property on your form to true. This worked for me for registering key presses.