KeyDown Event Key Not Work - VB.net - vb.net

KeyDown event does not work, pressing escape the form does not close
Private Sub DataTable_KeyDown(sender As Object, e As KeyEventArgs) Handles MyBase.KeyDown
If e.KeyCode = Keys.Escape Then
Me.Close()
End If
End Sub

Well, sure it works, the event is just not very like to fire. Keystrokes raise the KeyDown event on the control with the focus. That will only ever be your form when it has no controls that can get the focus. A fairly unlikely scenario.
If you already have a Button labeled "Cancel" that closes the form then set the form's CancelButton property.
If you don't have such a button then it gets to be pretty unlikely that the user will figure out by himself that the Escape key is useful. He will most likely use the Close button in the upper right corner. You can nevertheless make it work by overriding the ProcessCmdKey() method. Like this:
Protected Overrides Function ProcessCmdKey(ByRef msg As Message, keyData As Keys) As Boolean
If keyData = Keys.Escape Then
Me.Close()
Return True
End If
Return MyBase.ProcessCmdKey(msg, keyData)
End Function

Related

Why DateTimePicker won't trigger keyDown and KeyPress events with the tab key?

Fellows, I am having this problem - the DateTimePicker won't trigger KeyDown and KeyPress events with the tab key (other keys are working fine, and the keyUp event as well, although it triggers after "arriving" at the DateTimePicker after pressing tab at the previous control focused). I'm using .net 4.6.1, Visual Basic and VS 2017.
What I'm trying to do -> Go to month and year directly on DateTimePicker in C# (Go to month and year directly on DateTimePicker)
Code I'm using:
Private Sub DateTimePicker1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles DateTimePicker1.KeyDown
If e.KeyCode = Keys.Tab Then
e.Handled = True
MsgBox("TAB DOWN")
End If
End Sub
Private Sub DateTimePicker1_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles DateTimePicker1.KeyPress
e.Handled = True
MsgBox("tab press")
End Sub
Private Sub DateTimePicker1_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles DateTimePicker1.KeyUp
If e.KeyCode = Keys.Tab Then
MsgBox("TAB UP")
e.Handled = True
End If
End Sub
Any clues?
The Tab key is used for navigation. Moving the focus from one control to another. So your KeyDown event handler can never see it, the keystroke is intercepted and used before that. You could subscribe the PreviewKeyDown event and set the e.IsInputKey = true as a workaround, check the MSDN sample code in the linked article for code.
But it is the wrong event to use anyway, you'd still want this to work when the user changes focus with the mouse instead of the keyboard. So use the Enter event instead.
Do beware that both approaches have the same problem, the focus might already be on the month part from previous usage of the control so now your code will incorrectly move it to the year part. And you can't find out what part has the focus, that is up a creek without a good paddle. A very ugly workaround for that is to change the Format property, and back, that forces the control to re-create the control window and that always resets the focus. Use BeginInvoke() to run that code. Perhaps more constructively, consider to just not display the day if you are only interested in month+year, CustomFormat property.
Sample code that implements the focus hack:
Private Sub DateTimePicker1_Enter(sender As Object, e As EventArgs) Handles DateTimePicker1.Enter
Me.BeginInvoke(
New Action(Sub()
'' Hack to reset focus
DateTimePicker1.Format = DateTimePickerFormat.Long
DateTimePicker1.Format = DateTimePickerFormat.Short
DateTimePicker1.Focus()
SendKeys.Send("{Right}")
End Sub))
End Sub
It's not the right answer to this question, although it helps as well. If you want to just make the tab behave as the right key when inside a DateTimePicker, a good (sketchy) way to do is:
Private i = 2
Protected Overrides Function ProcessTabKey(ByVal forward As Boolean) As Boolean
Dim ctl As Control = Me.ActiveControl
If ctl IsNot Nothing AndAlso TypeOf ctl Is DateTimePicker And i <> 0 Then
SendKeys.Send("{Right}")
i -= 1
Return True
End If
i = 2
Return MyBase.ProcessTabKey(forward)
End Function
You need to override ProcessCmdKey function
Private isTab As Boolean = False
Private isShiftTab As Boolean = False
Protected Overrides Function ProcessCmdKey(ByRef msg As Message, ByVal keyData As Keys) As Boolean
If keyData = Keys.Tab Then
isTab = True
'Do something with it.
Else
isTab = False
End If
Return MyBase.ProcessCmdKey(msg, keyData)
End Function

Set Focus to a text box when F1 is pressed

I have been trying to get this to work but it's doing my head in, wondered if you experts can help me out.
On my form I would like to set focus to a TextBox when I press F1 on the keyboard, I have the code written but somehow it does not work when I press F1. What am I doing wrong? I have also set keypreview to true.
The code here:
Private Sub Form1_KeyUp(sender As Object, e As KeyEventArgs) Handles Me.KeyUp
If e.KeyData = Keys.F1 Then
txtemployeeno.Focus()
End If
End Sub
The problem is that your KeyUp event isn't firing because the form doesn't technically have input focus (though it may be activated). If you wish to use the KeyPreview property, you need to use the KeyPress event instead of KeyUp.
Alternatively, you could always override the ProcessCmdKey function. Just add the following method to your form's code:
Protected Overrides Function ProcessCmdKey(ByRef msg As Message, keyData As Keys) As Boolean
If keyData = Keys.F1 Then
txtemployeeno.Focus()
Return True
End If
Return MyBase.ProcessCmdKey(msg, keyData)
End Function

How to tell when Tab is pressed in TextBox

How can I tell if the Tab key has been pressed inside a certain textbox.
I tried enabling the AcceptsTab property to true and creating a function that handles texstboxname.KeyPress event, but when I tab while inside it it just tabs out of the box, instead of hitting my event. (normal keys fire my event, but tab never even fires it)
The Multiline property needs to be true as well.
From MSDN (emphasis in bold)
Gets or sets a value indicating whether pressing the TAB key in a multiline text box control types a TAB character in the control instead of moving the focus to the next control in the tab order.
so set the Multiline property to true.
As MiniTech also pointed out, KeyDown is easier to handle since it provides you with an e.KeyCode property whereas the KeyPress event only provides an e.KeyChar property.
Private Sub TextBox1_KeyDown(sender As Object, e As KeyEventArgs) _
Handles TextBox1.KeyDown
If e.KeyCode = Keys.Tab Then
'user pressed the Tab key...
End If
End Sub
It seems that you can either Additionally
Enable the multiline property on the TextBox
You can override IsInputKey before the Keydown or Keypress event first.
To do that you could derive a class from TextBox and ovverride it there, ( as Hans Passat suggested)
or you can also handle the PreviewKeyDown event and ovverride the IsInputKey to true in there.
I went with the second part of option two, so that I wouldn't have to worry about the multiline property being on and could Leave my code with the keypress event
Private Sub txtEntryBar_PreviewKeyDown(sender As Object, e As PreviewKeyDownEventArgs) Handles txtEntryBar.PreviewKeyDown
If e.KeyData = Keys.Tab Then
e.IsInputKey = True
End If
End Sub
Ref: http://www.vbforums.com/showthread.php?670904-Detecting-when-the-tab-key-is-pressed-in-a-textbox&p=4124911&viewfull=1#post4124911

Change action in Control + F4 Vb.net

My application is parent, child application. Child forms shows then press cntrl + F4 the child form is closed. How to block the action and the same time if i press cntrl + F4 the child form have submit button that event is invoked.
How can i do that?
I am using below coding is block the control + F4
Protected Overrides Function ProcessCmdKey(ByRef msg As Message, ByVal keyData As Keys) As Boolean
If keyData = Keys.Control Or Keys.F4 Then Return True
Return MyBase.ProcessCmdKey(msg, keyData)
End Function
This event already exists, the FormClosing event fires. You can cancel the close by setting e.Cancel = True in your event handler for the event. Be sure to check the e.CloseReason before you do that.
Do avoid breaking standard Windows shortcut keystrokes, there is no point. The user can also close the window by clicking the child window's Close button. Ctrl+F4 is just a helpful shortcut to do the same thing without using the mouse.
You have to catch the form closing event, then test if it's done by key-press.
I assume you mean ALT-F4?
Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
If My.Computer.Keyboard.AltKeyDown Then e.Cancel = True
End Sub
Or even shorter;
e.Cancel=My.Computer.Keyboard.AltKeyDown

vb.net Keydown event on whole form

I have a form with several controls. I want to run a specific sub on keydown event regardless any controls event.
I mean if user press Ctrl+S anywhere on form it execute a subroutine.
You should set the KeyPreview property on the form to True and handle the keydown event there
When this property is set to true, the form will receive all KeyPress,
KeyDown, and KeyUp events. After the form's event handlers have
completed processing the keystroke, the keystroke is then assigned to
the control with focus. .......... To handle keyboard
events only at the form level and not allow controls to receive
keyboard events, set the KeyPressEventArgs.Handled property in your
form's KeyPress event handler to true.
So, for example, to handle the Control+S key combination you could write this event handler for the form KeyDown event.
Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As KeyEventArgs) Handles MyBase.KeyDown
If e.Control AndAlso e.KeyCode = Keys.S then
' Call your sub method here .....
YourSubToCall()
' then prevent the key to reach the current control
e.Handled = False
End If
End Sub
I've used this code in my forms before and it seems to work pretty good.
Protected Overrides Function ProcessKeyPreview(ByRef m As System.Windows.Forms.Message) As Boolean
If m.Msg = &H100 Then 'WM_KEYDOWN
Dim key As Keys = m.WParam
If key = Keys.S And My.Computer.Keyboard.CtrlKeyDown Then
'DO stuff
Return True
End If
End If
Return MyBase.ProcessKeyPreview(m)
End Function