Zachet
Zachet

Reputation: 47

VB.NET: Manipulating TextBox Input: Dash every 5 characters and removing special characters

Essentially I am trying to replicate the Windows 7 (In-Windows) activation key TextBox form. The Form where it will auto capitalize letters, remove or deny all non alphanumeric characters except dashes every 5 characters that will be auto-input.

I assume this can be done with a fairly complicated replacement Regular Expression but I cannot seem to create one to fit the needs.

This is an Example of what I have right now, but it creates an infinite loop as it removes all characters including dashes, than adds a dash, which changes the text and removes the dash again.

Any suggestions, solutions or ideas would be appreciated!

Code modified from original question to the solution I am using:

      Private Sub aKeyTextField_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles aKeyTextField.KeyPress
    'Test only
    If Char.IsLetterOrDigit(e.KeyChar) Then
        Dim test As String = ""
        Select Case e.KeyChar
            Case "0" To "9"
                ' Do nothing
            Case "a" To "z"
                e.KeyChar = Char.ToUpper(e.KeyChar)
            Case Else
                e.Handled = True
        End Select
    ElseIf Not e.KeyChar = Convert.ToChar(8) Then

        e.KeyChar = ""
        End If


        Dim strKeyTextField As String = aKeyTextField.Text
        Dim n As Integer = 5
    Dim intlength As Integer = aKeyTextField.TextLength

    If Not e.KeyChar = Convert.ToChar(8) Then

        While intlength > 4 And intlength < 29

            If aKeyTextField.Text.Length = 5 Then
                strKeyTextField = strKeyTextField.Insert(5, "-")

            End If

            Dim singleChar As Char
            singleChar = strKeyTextField.Chars(n)

            While (n + 5) < intlength

                If singleChar = "-" Then
                    n = n + 6

                    If n = intlength Then
                        strKeyTextField = strKeyTextField.Insert(n, "-")
                    End If
                End If

            End While

            intlength = intlength - 5
        End While
        aKeyTextField.Text = strKeyTextField

        'sets focus at the end of the string
        aKeyTextField.Select(aKeyTextField.Text.Length, 0)


    Else

        Select Case aKeyTextField.Text.Length
            Case 7
                strKeyTextField = strKeyTextField.Remove(5, 1)
            Case 13
                strKeyTextField = strKeyTextField.Remove(11, 1)
            Case 19
                strKeyTextField = strKeyTextField.Remove(17, 1)
            Case 25
                strKeyTextField = strKeyTextField.Remove(23, 1)
            Case Else



        End Select

        aKeyTextField.Text = strKeyTextField
        aKeyTextField.Select(aKeyTextField.Text.Length, 0)

    End If

End Sub

Public Sub New()

    ' This call is required by the designer.
    InitializeComponent()

    ' Add any initialization after the InitializeComponent() call.
    Dim blankContextMenu As New ContextMenu
    aKeyTextField.ContextMenu = blankContextMenu


End Sub

Upvotes: 1

Views: 4243

Answers (4)

Standage
Standage

Reputation: 1517

This works, it could prob do with tidying up and comments but I just wanted to see if I could get this working:

Private Sub aKeyTextField_KeyPress(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles aKeyTextField.KeyPress
    'Test only
    If Char.IsLetterOrDigit(e.KeyChar) Then
        Dim test As String = ""
        Select Case e.KeyChar
            Case "0" To "9"
                ' Do nothing
            Case "a" To "z"
                e.KeyChar = Char.ToUpper(e.KeyChar)
            Case Else
                e.Handled = True
        End Select
    Else
        e.KeyChar = ""
    End If


    Dim strKeyTextField As String = aKeyTextField.Text
    Dim n As Integer = 5
    Dim intlength As Integer = aKeyTextField.TextLength
    While intlength > 4

        If aKeyTextField.Text.Length = 5 Then
            strKeyTextField = strKeyTextField.Insert(5, "-")

        End If

        Dim singleChar As Char
        singleChar = strKeyTextField.Chars(n)

        While (n + 5) < intlength

            If singleChar = "-" Then
                n = n + 6

                If n = intlength Then
                    strKeyTextField = strKeyTextField.Insert(n, "-")
                End If
            End If

        End While

        intlength = intlength - 5
    End While
    aKeyTextField.Text = strKeyTextField

    'sets focus at the end of the string
    aKeyTextField.Select(aKeyTextField.Text.Length, 0)

End Sub

Upvotes: 1

Standage
Standage

Reputation: 1517

Look like you have the ^ in the wrong place here, it needs to be inside the square brackets, also remove the {5}-, this will then remove all the non alphanumeric characters.

 If m.Success Then
            aKeyTextField.Text = Regex.Replace(aKeyTextField.Text, "[^a-zA-Z0-9]+, "")"
            aKeyTextField.SelectionStart = aKeyTextField.TextLength
 End If

This code below will only put a - at the 5th position only and you need to add it to every 5 characters, create a loop / get the length and divide by 5 and add a "-" every 5 position.

If aKeyTextField.TextLength > 5 Then

        aKeyTextField.Text = aKeyTextField.Text.Insert(5, "-")
        aKeyTextField.SelectionStart = aKeyTextField.TextLength

  End If

Something like this would work instead:

Dim n As Integer = 5
        Dim intlength As Integer = aKeyTextField.Length
        While intlength > 0 And n < intlength
            aKeyTextField = aKeyTextField.Insert(n, "-")
            intlength = intlength - 5
            n = n + 6
        End While

To stop the infinite looping change the event to Validating instead:

Private Sub aKeyTextField_TextValidating(ByVal sender As Object, ByVal e As System.EventArgs) Handles aKeyTextField.Validating

Upvotes: 0

msarchet
msarchet

Reputation: 15242

I would suggest instead of doing this on the TextChangedEvent of the TextBox to handle this in the Set method of the property that you are backing the textbox with.

Upvotes: 0

Simon
Simon

Reputation: 6152

Have a look at the MaskedTextBox. You should be able to achieve your aims with little code and not need the regex.

Upvotes: 3

Related Questions