Enter and Tab sends focus to next textbox - vb.net

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

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

User TexBox won't handle Escape key

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.

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

Use ENTER or RETURN as TAB in form and panels

My form as multiple controls like Textboxes and Panels, and Textboxes in Panels, which cause problem. I try to make keys ENTER and RETURN do the same as TAB, so select next control, but for an unknown reason if I i go from any control to a panel, it doesn't enter the first control in the panel, it skips to the next control which isn't a panel.
My form key preview is already True and my tab index are okay :
First textbox is 10, first panel 11, first textbox of panel 12. For now it skips to 20, next textbox not in a panel.
Code based on this question : Tab Key Functionality Using Enter Key in VB.Net
Here is my code
Private Sub Values_KeyDown(ByVal sender As Control,
ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
If e.KeyCode = Keys.Return Or e.KeyCode = Keys.Enter Then
If TypeOf Me.GetNextControl(Me.ActiveControl, True) Is Panel Then
Me.SelectNextControl(CType(Me.ActiveControl, Panel).Controls.Item(0), True, True, False, True)
Else
Me.SelectNextControl(Me.ActiveControl, True, True, False, True)
End If
e.Handled = True
End If
End Sub
Thanks!
I don't really understand the code snippet, it looks like the last attempt before giving up. Nor how it got to run at all, KeyPreview is not good enough to intercept KeyDown for the navigation keys like the Enter key. The nested argument for SelectNextControl() should not certainly not be False, you do want to consider controls that are nested inside a panel as the next tab target, presumably what made the code jump off the rails.
I'll post a more universal solution that does not depend on KeyPreview and still properly deals with controls that need the Enter key to function correctly. Simply copy/paste it into the form, it does not use events:
Protected Overrides Function ProcessCmdKey(ByRef msg As Message, keyData As Keys) As Boolean
Dim dotab = False
Dim ctl = Me.ActiveControl
If ctl IsNot Nothing And keyData = Keys.Enter Then
dotab = True
If TypeOf ctl Is TextBoxBase Then
If DirectCast(ctl, TextBoxBase).Multiline Then dotab = False
End If
End If
If dotab Then
If Me.SelectNextControl(ctl, True, True, True, True) Then Return True
End If
Return MyBase.ProcessCmdKey(msg, keyData)
End Function
With Hans' answer i manage to make it work by simply changing the nested parameter to true and get rid of the part that was suppose to make it work with panels, like this:
Private Sub Values_KeyDown(ByVal sender As Control, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
If e.KeyCode = Keys.Return Or e.KeyCode = Keys.Enter Then
Me.SelectNextControl(Me.ActiveControl, True, True, True, True)
e.Handled = True
End If
End Sub
You'll still need to put the Key Preview parameter on your form to True
I also found an alternative here : How to make Enter on a TextBox act as TAB button
Private Sub Values_KeyDown(ByVal sender As Control, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
If e.KeyCode = Keys.Return Or e.KeyCode = Keys.Enter Then
SendKeys.Send("{TAB}")
e.Handled = True
End If
End Sub
Use processTabKey(true) function

How to embed a Console in a Windows Form application?

I'm trying to build a Text Adventure game in VB.net, just like the days of old. The obvious choice would be a Console application, however, I have decided on a Windows Form because I am hoping to include interactive buttons and pictures. Currently, I have already got on my form a picture box and a Rich Text Box. I was hoping that with the Rich Text Box I could achieve something that worked in the same way as a console. Alas, my efforts are futile. Everything I have tried has failed, including: reading Rich_Text_Box.Text and Rich_Text_Box_KeyUp with an if statement for enter being pressed to call the procedure for an enter button.
I was wondering if there was any way to include a Console with standard Console.WriteLine and Console.ReadLine capabilities inside of my Form? This would very much shorten my task and streamline the whole process.
Any ideas?
You could use not one but two Textboxes for your purpose. tbOutput and tbInput. tbOutput would be Multiline and ReadOnly whereas tbInput would be single line, not readonly and placed beneath tbOutput. Then to process inputs you could do something like:
Private Sub Output(s As String)
If s <> "" Then
tbOutput.AppendText(vbCrLf & ">> " & s)
End If
End Sub
Private Sub tbInput_KeyDown(sender As Object, e As KeyEventArgs) Handles tbInput.KeyDown
If e.KeyCode = Keys.Enter Then
If tbInput.Text <> "" Then
Output(tbInput.Text)
' Handle input value
tbInput.Text = ""
End If
End If
End Sub
At the 'Handle input value you would check the user input and handle it according to your needs. Use Lucida Console font in bold in gray and black background for style :-)
Sure, a RichTextBox can be used to emulate a console. Some surgery is required to avoid the user from making it malfunction as a console. Add a new class to your project and paste the code shown below. Compile. Drop the new control from the top of the toolbox onto your form. Subscribe the InputChanged event to detect when the user presses the Enter key, the Input property gives you the typed text. Use the Write() or WriteLine() methods to add text.
Imports System.Windows.Forms
Public Class RichConsole
Inherits RichTextBox
Public Event InputChanged As EventHandler
Public ReadOnly Property Input() As String
Get
Return Me.Text.Substring(InputStart).Replace(vbLf, "")
End Get
End Property
Public Sub Write(txt As String)
Me.AppendText(txt)
InputStart = Me.SelectionStart
End Sub
Public Sub WriteLine(txt As String)
Write(txt & vbLf)
End Sub
Private InputStart As Integer
Protected Overrides Function ProcessCmdKey(ByRef m As Message, keyData As Keys) As Boolean
'' Defeat backspace
If (keyData = Keys.Back OrElse keyData = Keys.Left) AndAlso InputStart = Me.SelectionStart Then Return True
'' Defeat up/down cursor keys
If keyData = Keys.Up OrElse keyData = Keys.Down Then Return True
'' Detect Enter key
If keyData = Keys.[Return] Then
Me.AppendText(vbLf)
RaiseEvent InputChanged(Me, EventArgs.Empty)
InputStart = Me.SelectionStart
Return True
End If
Return MyBase.ProcessCmdKey(m, keyData)
End Function
Protected Overrides Sub WndProc(ByRef m As Message)
'' Defeat the mouse
If m.Msg >= &H200 AndAlso m.Msg <= &H209 Then Return
MyBase.WndProc(m)
End Sub
End Class