User TexBox won't handle Escape key - vb.net

I made a MyTextMain custom control
I added the property:
Public Property PressedEscape As Boolean = False
 and
Private Sub MyTextMain_KeyUp (ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyUp 
If e.KeyCode = Keys.Escape Then Me.PressedEscape = True
End Sub
 
However, when I add a TextBox to any new form, the focus is on that control, I press ESC and the property does not change.
I tried the KeyPreview property of the form with True and False and the same.
Where is the error?

Override the ProcessCmdKey in your custom TextBox control:
Protected Overrides Function ProcessCmdKey(ByRef msg As Message, keyData As Keys) As Boolean
If keyData = Keys.Escape Then
Me.PressedEscape = True
End If
Return MyBase.ProcessCmdKey(msg, keyData)
End Function
Making PressedEscape a property seems like an odd choice. I would re-think that depending on what you are doing with it.

Related

How to clear all contents of textbox when spacebar is pressed? VB.Net

I'm creating a simple typing test program.
I want the space bar to trigger checking if the typed word is correct, then clear the contents of the textbox.
What happens here is the first typed word will work and be counted when the space bar is pressed and the typed word will be cleared, but the space character still remains and so the next typed word will contain a space char and will be read wrong.
I tried interchanging where the txtInput.Clear() should be placed but results in the same problem.
Private Sub txtInput_TextChanged(sender As Object, e As KeyEventArgs) Handles txtInput.KeyDown
If e.KeyValue = Keys.Space Then
Space()
End If
End Sub
Public Function Space()
If txtInput.Text = txtWord.Text Then
ctr = CInt(txtWord.TextLength)
charTotal = charTotal + ctr
lblScore.Text = charTotal.ToString
End If
txtInput.Clear()
txtWord.Text = rdmWord()
End Function
In KewDown Event the value of TextBox isnot setted yet. So, use KeyUp Event as the code below shows
Private Sub txtInput_KeyUp(sender As Object, e As KeyEventArgs) Handles txtInput.KeyUp
If e.KeyValue = Keys.Space Then
Space()
End If
End Sub
You could also override ProcessCmdKey and trap the spacebar there:
Protected Overrides Function ProcessCmdKey(ByRef msg As Message, keyData As Keys) As Boolean
If keyData = Keys.Space Then
If Me.ActiveControl Is txtInput Then
Space()
Return True ' suppress space
End If
End If
Return MyBase.ProcessCmdKey(msg, keyData)
End Function
If you want to allow space or enter, then change to:
If keyData = Keys.Space Or keyData = Keys.Enter Then

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

How to prevent ALT+F4 of a WinForm but allow all other forms of closing a WinForm?

I've searched around the interwebs and various parts of this resource where this question was asked and noticed I got the following bits of code:
Protected Overrides ReadOnly Property CreateParams() As CreateParams
Get
Dim cp As CreateParams = MyBase.CreateParams
Const CS_NOCLOSE As Integer = &H200
cp.ClassStyle = cp.ClassStyle Or CS_NOCLOSE
Return cp
End Get
End Property
Which works as intended, this does disable ALT+F4 from being used. However, as an unintended side effect of this code: closing the window via the Control Box is disabled:
Is there a version of this code that disables ALT+F4 BUT still allows for the closing of the window via its control box or other UI options (such as a close button and a Close option in a menu.)
I know someone will say to check the e.CloseReason of the form, however UserClosing is the only reason the resembles what I would like to do, however... that still disables the UI from being used. Unless there is a code that I forgot about.
Set KeyPreview = True and handle the KeyDown event:
Private Sub Form1_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
If e.Alt AndAlso e.KeyCode = Keys.F4 Then
e.Handled = True
End If
End Sub
Answer to your comment, handling KeyDown from a separate class.
Documentation:
AddHandler statement
Shared access modifier
Public NotInheritable Class MainInterface
Private Sub New() 'No constructor.
End Sub
Public Shared Sub DisableAltF4(ByVal TargetForm As Form)
TargetForm.KeyPreview = True
AddHandler TargetForm.KeyDown, AddressOf Form_KeyDown
End Sub
Private Shared Sub Form_KeyDown(sender As Object, e As KeyEventArgs)
e.Handled = (e.Alt AndAlso e.KeyCode = Keys.F4)
End Sub
End Class
Now in every form's Load event handler you can do:
Private Sub yourForm_Load(sender As Object, e As EventArgs) Handles MyBase.Load
MainInterface.DisableAltF4(Me)
End Sub
As Olaf said you can also make all forms inherit from a base class. However this might get a little bit more complicated as you have to tell both the yourForm.vb and the yourForm.Designer.vb file that you want to inherit from the base form.
Public Class BaseForm
Inherits Form
Protected Overrides Sub OnLoad(e As System.EventArgs)
MyBase.OnLoad(e)
Me.KeyPreview = True
End Sub
Protected Overrides Sub OnKeyDown(e As System.Windows.Forms.KeyEventArgs)
MyBase.OnKeyDown(e)
e.Handled = e.Handled OrElse (e.Alt AndAlso e.KeyCode = Keys.F4)
End Sub
End Class
In yourForm.vb:
Public Class yourForm
Inherits BaseForm
...code...
End Class
In yourForm.Designer.vb:
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Partial Class yourForm
Inherits yourNamespace.BaseForm
...code...
End Class
You should also remove the corresponding CLOSE menu item from the forms system menu using a RemoveMenu() interop call. This disables all default window close options.
Of course you can call Form.Close() in your code to close your form. That can be triggered by a Click event handler of a custom button, menu item etc. Additionally, you can implement an System.Windows.Forms.IMessageFilter to handle a custom key sequence (instead of ALT+F4) to close your form, e.g. C+L+O+S+E.
Easy:
In C#
protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
{
if (keyData == (Keys.Alt | Keys.F4))
{
return true; // The key is manually processed
}
else
return base.ProcessCmdKey(ref msg, keyData);
}
In VB.Net
Protected Overrides Function ProcessCmdKey(ByRef msg As Message, ByVal keyData As Keys) As Boolean
If keyData = (Keys.Alt Or Keys.F4) Then
Return True
Else
Return MyBase.ProcessCmdKey(msg, keyData)
End If
End Function

Enter and Tab sends focus to next textbox

I had made a class by inheriting the system textbox shown in following code.
Public Class textboxex
Inherits TextBox
Private Sub TextBoxEx_Return(sender As Object, e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
If e.KeyCode = Keys.Enter Then
SendKeys.Send("{TAB}")
Me.Text = Me.Text.ToUpper 'To change the text to upper case when it leaves focus.(working fine)
End If
End Sub
Now problem is when I press Tab key, it doesn't enter the if condition.
Probably it would not because I havn't given if condition for tab key.
But I after I changed the if condition by adding e.keycode = keys.Tab and pressing tab key, it won't do the Uppercase of the letters but enter does it fine. The updated code shown below.
If e.KeyCode = Keys.Enter or e.KeyCode = Keys.Tab Then
SendKeys.Send("{TAB}")
Me.Text = Me.Text.ToUpper 'doesn't work when tab is pressed | enter works fine
End If
So this is my problem, help me plox...!!!!!!!
To make Enter work like Tab
You can override ProcessCmdKey method and check if the key is Enter then, send a Tab key or ussing SelectNextControl, move focus to next control:
Public Class MyTextBox
Inherits TextBox
Protected Overrides Function ProcessCmdKey(ByRef msg As Message, keyData As Keys) _
As Boolean
If (keyData = Keys.Enter) Then
SendKeys.Send("{TAB}")
'Parent.SelectNextControl(Me, True, True, True, True)
Return True
End If
Return MyBase.ProcessCmdKey(msg, keyData)
End Function
End Class

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