KnowDotNet

Smart TextBoxes

Making TextBoxes Work Like MaskedEdit

by Les Smith

In VB6, there was a MaskedEdit Control, but it could not be right justified.  Windows Forms in .NET does not have a MaskedEdit Control.  This article will create a TextBox that behaves like a VB6 MaskedEdit Control, only it can be right justified, and it is all done with code, not a 3rd party control.

I once had the job of replacing Excel functionality with a VB6 Application.  In other words, the user wanted all TextBoxes to work like Excel cells with respect to formatting.  Additionally, they wanted them to behave like MaskedEdit Controls so that the input was validated as it was entered, and they wanted currency data to be right justified.  The problem was that the VB6 MaskedEdit Control did not have a property that would allow right justification.  So I wrote add-in code to automatically generate the code that I am going to demonstrate in this article.  The code, shown below, is automatically generated by the TextBox Designer that comes with
NetCommander.  NetCommander can generate this code in both VB.NET and C# projects.  You can download a fully feature copy for a free 30-day trial by clicking here.  

For almost all TextBoxes, that are used for input, you want them to have the following attributes.

   1. The text should be highlighted upon receiving focus so that the user can input into the control without having to delete the previous text.
   2. An Enter key should work just like a Tab key, and it should not Beep.
   3. The Up and Down arrow keys should work like the Tab key.

In order to add this functionality to a TextBox, I always add the following code behind each one that is used for data input.

   ' Prevents the Enter key from Beeping
   Private Sub TextBox1_KeyPress(ByVal sender As Object, _
      
ByVal e As System.Windows.Forms.KeyPressEventArgs) _
      
Handles TextBox1.KeyPress
      
If e.KeyChar = Chr(13) Then
         e.Handled = True
         Exit Sub
      End If
   End Sub

   ' turns Enter, Up, and Down Keys into Tabs
   Private Sub TextBox1_KeyDown(ByVal sender As Object, _
      
ByVal e As System.Windows.Forms.KeyEventArgs) _
      
Handles TextBox1.KeyDown
      
If e.KeyCode = Keys.Enter Then SendKeys.Send("{TAB}")
      
If e.KeyCode = Keys.Up Then SendKeys.Send("+{TAB}")
      
If e.KeyCode = Keys.Down Then SendKeys.Send("{TAB}")
  
End Sub

   ' Selects the contents of the control on receiving focus
   Private Sub TextBox1_Enter(ByVal sender As Object, _
      
ByVal e As System.EventArgs) Handles TextBox1.Enter
      TextBox1.Text = UnFmt_T_B(TextBox2)
      TextBox1.SelectionStart = 0
      TextBox1.SelectionLength = TextBox1.Text.Trim.Length
  
End Sub

In order to create the MaskedEdit "look-a-like" code, I added additional code (in Bold Font) to the KeyPress event and added code to the Leave Event.  

   ' Prevents the Enter key from Beeping
   ' and calls the keystroke validation method
   Private Sub TextBox2_KeyPress(ByVal sender As Object, _
      
ByVal e As System.Windows.Forms.KeyPressEventArgs) _
      
Handles TextBox2.KeyPress
      
If e.KeyChar = Chr(13) Then
         e.Handled = True
         Exit Sub
      End If
      e.Handled = CkKeyPressNumeric(Asc(Val(e.KeyChar)), TextBox2) = 0
   End Sub

   ' Selects the contents of the control on receiving focus
   ' after it is unformatted
   Private Sub TextBox2_Enter(ByVal sender As Object, _
      
ByVal e As System.EventArgs) Handles TextBox2.Enter
      
TextBox2.Text = UnFmt_T_B(TextBox2)
      TextBox2.SelectionStart = 0
      TextBox2.SelectionLength = TextBox2.Text.Trim.Length
  
End Sub

   ' Formats the code according to the format specified
   ' in the Tag property of the control
   Private Sub TextBox2_Leave(ByVal sender As Object, _
      
ByVal e As System.EventArgs) Handles TextBox2.Leave
      
TextBox2.Text = Fmt_T_B(TextBox2)
   End Sub

The following code is the helper functions that format, unformat, and validate input.  Please forgive the code leftover from VB6.  It was migrated and has not been updated.  But, you can get the picture.


   ' Format contents of textbox when it loses focus.
   Public Function Fmt_T_B(ByVal roTB As TextBox) As String
      On Error Resume Next
      If InStr(1, roTB.Tag, ";", 1) > 0 Then
         If InStr(roTB.Text, "-") > 0 Or _
            (InStr(roTB.Text, "(") > 0
And _
            InStr(roTB.Text, ")") > 0)
Then
            Return Format(Math.Abs(Val(roTB.Text)), _
               Mid$(roTB.Tag, InStr(roTB.Tag, ";") + 1))
        
Else
            Return Format$(Math.Abs(Val(roTB.Text)), _
               Microsoft.VisualBasic.Left(roTB.Tag, _
               InStr(roTB.Tag, ";") - 1))
        
End If
      ElseIf InStr(1, roTB.Tag, "%", 1) > 0 Then
         Return Format$(roTB.Text, roTB.Tag)
      
Else
         Return Format$(roTB.Text, roTB.Tag)
      
End If
   End Function

   ' Unformat the textbox when it receives focus
   Public Function UnFmt_T_B(ByVal roTB As TextBox) As Object
      On Error Resume Next
      UnFmt_T_B = Val(Replace(Replace(Replace(Replace(Replace _
        (roTB.Text, "$", ""), ",", ""), ")", ""), "(", ""), "%", ""))
      
If InStr(roTB.Text, "%") Then
         UnFmt_T_B = UnFmt_T_B / 100
      
End If
      If InStr(roTB.Text, "(") > 0 And InStr(roTB.Text, ")") > 0 Then
         UnFmt_T_B = UnFmt_T_B * -1
      
End If
      Return UnFmt_T_B
  
End Function

   ' validate keyboard input
   Private Function CkKeyPressNumeric(ByVal riKeyAscii As Integer, _
      
ByVal roTB As TextBox) As Integer
      Dim liKeyReturn As Integer
      ' allow 0-9,., Back, Del,-,Ins, and / if in tag format
      On Error Resume Next
      CkKeyPressNumeric = riKeyAscii
      
If riKeyAscii = Keys.Back Or _
         riKeyAscii = Keys.Insert
Or _
         riKeyAscii = Keys.Delete
Or _
         riKeyAscii = 46
Or _
         (riKeyAscii >= Keys.D0
And riKeyAscii <= Keys.D9) Or _
         riKeyAscii = 45
Or _
         riKeyAscii = 46
Or _
         (InStr(roTB.Tag, "/") > 0
And riKeyAscii = Keys.Divide) _
        
Then
         If roTB.SelectionLength = 0 Then
            If InStr(roTB.Text, ".") > 0 Then
               If Len(Mid(roTB.Text, InStr(roTB.Text, ".") + 1)) > 1 Then
                  SendKeys.Send("{TAB}")
                  CkKeyPressNumeric = 0
              
End If
            End If
         Else
            roTB.Text = ""
        
End If
         Return CkKeyPressNumeric
      
End If
      Return 0
  
End Function

Figure 1 shows the Tag property of a Smart TextBox.  Several other formats are usable in the Tag property, which directs the helper methods in the process of formatting and validating the contents of the TextBox.

Figure 1 - Smart TextBox Properties.

SmartTB


Figure 2 shows a simple application which as several Smart TextBoxes.  One of them has focus and you can see that the formatting characters have been removed and the text is selected and ready to be overlaid by any input.  If focus moves away from that box without any new input, it will be reformatted and appear as the other TextBoxes.

Figure 2 - Smart TextBoxes in Action.

SM2


Top of Page