الاثنين، 12 ديسمبر 2011

Smart TextBoxes


Smart TextBoxes

Making TextBoxes Work Like MaskedEdit

by Les Smith
Print this ArticleDiscuss in Forums

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

ليست هناك تعليقات:

إرسال تعليق