I suggest using regex (regular expressions). What you have to do is checking each and every single character that the user enters. If the characters are invalid you have to replace them with valid characters. In the following code example, the user is required to enter date in the format YYYY-MM-DD.HH:mm. A string such as 2021-02-03.45:10 conforms to the format. But if the user does not enter a valid character, the entered character is going to be replaced with a valid character. If the user enters ASCII characters, he will get the current date and time in the textbox.
In regular expressions "([0-9])" matches with a single digit. "\." matches with a dot, and ":" matches with a : character.
For the code to work you must import the following namespaces:
Imports System
Imports System.Globalization
Imports System.Text.RegularExpressions
Private Sub TbxDate_TextChanged(sender As Object, e As EventArgs) Handles TbxDate.TextChanged
Dim dtNow As System.DateTime = DateAndTime.Now
Dim Y As Integer = dtNow.Year
Dim sYear As String = CStr(Y)
Dim Ys1 As String = sYear.Substring(0, 1)
Dim Ys2 As String = sYear.Substring(1, 1)
Dim Ys3 As String = sYear.Substring(2, 1)
Dim Ys4 As String = sYear.Substring(3, 1)
Dim M As Integer = dtNow.Month
Dim sMonth As String = CStr(M)
Dim Ms1 As String = 0
Dim Ms2 As String = 0
If M >= 10 Then
Ms1 = sMonth.Substring(0, 1)
End If
Ms2 = sMonth.Substring(0, 1)
Dim D As Integer = dtNow.Day
Dim sDay As String = CStr(D)
Dim Ds1 As String = 0
Dim Ds2 As String = 0
If D >= 10 Then
Ds1 = sMonth.Substring(0, 1)
End If
Ds2 = sDay.Substring(0, 1)
Dim H As Integer = dtNow.Hour
Dim sHour As String = CStr(H)
Dim Hs1 As String = 0
Dim Hs2 As String = 0
If H >= 10 Then
Hs1 = sHour.Substring(0, 1)
End If
Hs2 = sHour.Substring(0, 1)
Dim patterns() As String = New String() {"([1-2])", "([0-9])", "([0-9])", "([0-9])",
"-",
"([0-9])", "([0-9])",
"-",
"([0-3])", "([0-9])",
"\.",
"([0-5])", "([0-9])",
":",
"([0-5])", "([0-9])"}
Dim rpChars() As String = New String() {Ys1, Ys2, Ys3, Ys4, "-", Ms1, Ms2, "-", Ds1, Ds2, ".", Hs1, Hs2, ":", "0", "0"}
Dim theText As String = Me.TbxDate.Text
Dim cursor1 As Integer = Me.TbxDate.SelectionStart
Dim cursor2 As Integer = cursor1
Dim L2 As Integer = 0
Dim L1 As Integer = 0
Dim finalText As String = ""
If theText IsNot Nothing AndAlso theText.Length >= 1 Then
For x As Integer = 0 To theText.Length - 1 Step +1
Dim pat As String = patterns(x)
Dim Letter As String = theText.Substring(x, 1)
Dim extStr As String = ExtractFirstString(Letter, pat)
If extStr <> Letter Then
extStr = rpChars(x)
finalText &= extStr
Else
finalText &= Letter
End If
Next
End If
If finalText <> theText Then
If finalText IsNot Nothing AndAlso finalText.Length >= 17 Then
finalText = finalText.Substring(0, 16)
End If
If finalText IsNot Nothing Then
L2 = finalText.Length
End If
If theText IsNot Nothing Then
L1 = theText.Length
End If
If L2 > L1 Then
cursor2 = cursor1 + (L2 - L1)
End If
Me.TbxDate.Text = finalText
Me.TbxDate.SelectionStart = cursor2
End If
End Sub
Private Function ExtractFirstString(ByVal sourceStr As String, ByVal pattern As String) As System.String
Dim mc As System.Text.RegularExpressions.MatchCollection
Dim result As String = Nothing
Dim i As Integer
Dim brk As Boolean = False
If sourceStr IsNot Nothing Then
' match email addresses!
mc = Regex.Matches(sourceStr, pattern)
If mc IsNot Nothing Then
Dim results(mc.Count - 1) As String
For i = 0 To results.Length - 1 Step +1
result = mc(i).Value
brk = True
Return result
Exit For 'only return the first match
Next
End If
End If
Return Nothing
End Function
Assign a length of 16 to the textbox when you are creating textbox.
Me.TbxDate.Dock = System.Windows.Forms.DockStyle.Top
Me.TbxDate.MaxLength = 16
Me.TbxDate.Name = "Tbx_Year"
Me.TbxDate.TabIndex = 0
The function ExtractFirstString checks the character to see if it conforms to the valid character or not.