VB.NET - How do I make a textbox only valid one character per key press?

My project is supposed to mimic an Enigma machine and I need help with the visual interface.

In my program, I need to have a textbox where the user can enter an unlimited number of letters. However, the program also updates other components based on the entered text and displays a visual representation to the user.

For example, when I press the letter "A", the program encodes it to say the letter "S" and displays an image in the interface. However, this encoding is unique for each letter encoding.

As you know, when you keep a letter pressed on the keyboard for a longer time, it continues to write that letter. For example, if I hold down the "A" key, I get "AAAAAAAAAAAAAAAAAAAAA" in my textbox, and it spams the image as it encodes each "A".

My question is, how can I restrict a textbox to accept only one letter per key press, but still allow a double or triple letter? Therefore, I can have a substring of the same characters if I enter them by pressing several times on the keyboard.

I need this to get the encoded leater to light up as long as the input letter is pressed.

+3


source to share


3 answers


If you are using SuppressKeyPress on KeyEventArgs, you can control when the key press is complete. In my example, I am using a textbox to input the control. But this will work with other controls too ...



Dim keyIsDown As Boolean 'marked to give status of keyboard key

Private Sub TextBox1_KeyDown(sender As Object, e As KeyEventArgs) Handles TextBox1.KeyDown
    If keyIsDown Then 'if key is already down abort
        e.SuppressKeyPress = True
        Exit Sub
    End If
    keyIsDown = True 'if key was not already down mark it as down now   
End Sub

Private Sub TextBox1_KeyUp(sender As Object, e As KeyEventArgs) Handles TextBox1.KeyUp
    keyIsDown = False 'key has traveled up clear the marker
End Sub

      

+2


source


Whether or not it is a duplicate key is not something you can learn from key events. But it is available in the basic WM_KEYDOWN message , bit # 30 of the lparam argument will be set to 1. The easiest way to take a look at this message is by overriding the ProcessCmdKey () method. Paste this code into your form class:

Private repeatedKey As Boolean

Protected Overrides Function ProcessCmdKey(ByRef msg As Message, keyData As Keys) As Boolean
    repeatedKey = (msg.LParam.ToInt32 And (1 << 30)) <> 0
    Return MyBase.ProcessCmdKey(msg, keyData)
End Function

      

You can now check this variable in the KeyPressed event handler. I would guess that you want to do something like this:



Private Sub TextBox1_KeyPress(sender As Object, e As KeyPressEventArgs) Handles TextBox1.KeyPress
    If repeatedKey Then e.Handled = True
    If e.KeyChar = ChrW(22) Then e.Handled = True '' Disable paste
    If e.KeyChar = ChrW(8) Then e.Handled = False '' Allow repeating backspace
End Sub

      

The first line prevents duplicate keys from being visible. The second line disables copy / paste, which is unlikely to be useful in your application. The third line still allows the backspace key to be repeated so that the user can easily correct the error. Keep in mind that I'm just guessing what you want to do here, this is just an example and you probably want to change it.

+3


source


You can use a boolean flag to determine if the first event has fired keypress

and then cancel any next one keypress

until the event occurs KeyUp

.

Private isKeyHandled As Boolean = False

Private Sub TextBox1_KeyPress(ByVal sender As Object, ByVal e As KeyPressEventArgs) _
Handles TextBox1.KeyPress

    e.Handled = Me.isKeyHandled 
    Me.isKeyHandled = True

End Sub

Private Sub TextBox1_KeyUp(ByVal sender As Object, ByVal e As KeyEventArgs) _
Handles TextBox1.KeyUp

    Me.isKeyHandled = False

End Sub

      

Also, for placement, you could add logic to the subclassed TextBox:

Public Class TextBoxEx : Inherits TextBox

    Public Property DisableKeyRepetition As Boolean = False

    Private isKeyHandled As Boolean = False

    Protected Overrides Sub OnKeyPress(ByVal e As KeyPressEventArgs)

        MyBase.OnKeyPress(e)

        If Me.DisableKeyRepetition Then
            e.Handled = Me.isKeyHandled
            Me.isKeyHandled = True
        End If

    End Sub

    Protected Overrides Sub OnKeyUp(ByVal e As KeyEventArgs)

        MyBase.OnKeyUp(e)
        Me.isKeyHandled = False

    End Sub

End Class

      

Then:

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load

    Me.TextBoxEx1.DisableKeyRepetition = True

End Sub

      

+2


source







All Articles