Here is the approach that I used. This post is a little long but it is
complete.
This textbox checks the entered text upon the user leaving the textbox, this
allows the user to edit the text and have an incorrect value part way
through
the editing sequence without interupting the user. If the text is not
correct on
leaving the textbox the user is presented a messagebox with a message
(setable
as a property) explaining the problem and the correct entry format. Note
that
the user can enter nothing (i.e. "") and is able to exit the textbox. I
hate getting
stuck in a textbox on some form and can't get out. Always check for a nil
entry.
Let me first say that this is heavly plagerized from an article at the MS
site
about Regular Expressions. I initally created a smart text box control that
could validate itself. Create a control library and a SmartTextBox control
as follows.
Imports System.Text.RegularExpressions
Public Class SmartTextBox
Inherits System.Windows.Forms.TextBox
#Region " Windows Form Designer generated code "
Public Sub New()
MyBase.New()
'This call is required by the Windows Form Designer.
InitializeComponent()
'Add any initialization after the InitializeComponent() call
Me.ValidationExpression = ".*"
End Sub
'UserControl1 overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub
'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer
'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
End Sub
#End Region
' String representation of the RegEx that will be used to
' validate the text in the TextBox. This is needed because
' the property needs to be exposed as a string to be set
' at design time.
Protected validationPattern As String
' Message that should be available if the text does not
' match the pattern.
Protected mErrorMessage As String
' RegEx object that's used to perform the validation.
Protected mValidationExpression As Regex
' Default color to use if the text in the TextBox is not
' valid.
Protected mErrorColor As Color = Color.Red
' Allow the developer to set the error message
' at design time or run time.
Public Property ErrorMessage() As String
Get
Return mErrorMessage
End Get
Set(ByVal Value As String)
mErrorMessage = Value
End Set
End Property
' If the TextBox text does not match the RegEx, then it
' will be changed to this color.
Public Property ErrorColor() As Color
Get
Return mErrorColor
End Get
Set(ByVal Value As Color)
mErrorColor = Value
End Set
End Property
' Let's the developer determine if the text in the TextBox
' is valid.
Public ReadOnly Property IsValid() As Boolean
Get
If Not mValidationExpression Is Nothing Then
Return mValidationExpression.IsMatch(Me.Text)
Else
Return True
End If
End Get
End Property
' Lets the developer specify the regular expression (as
' a string) that will be used to validate the text in the
' TextBox. It's important that this be setable as a string
' (vs. a RegEx object) so that the developer can specify
' the RegEx pattern using the properties window.
Public Property ValidationExpression() As String
Get
Return validationPattern
End Get
Set(ByVal Value As String)
mValidationExpression = New Regex(Value)
validationPattern = Value
End Set
End Property
' If the text does not match the RegEx, then change the
' color of the text to the ErrorColor. If it does match
' then make sure it's displayed using the default color.
Protected Overrides Sub OnValidated(ByVal e As System.EventArgs)
If Not Me.IsValid And Me.Text <> "" Then
Me.ForeColor = mErrorColor
Me.Focus()
MsgBox(mErrorMessage)
Else
Me.ForeColor = Me.DefaultForeColor
End If
' Any time you inherit a control, and override one of
' the On... subs, it's critical that you call the On...
' method of the base class, or the control won't fire
' events like it's supposed to.
MyBase.OnValidated(e)
End Sub
End Class
===========
Then I create a SmartDoubleTextBox that knows how to
check for a valid expression and then converts it into a
NumericValue that is available to the developer as a property
Public Class SmartDoubleTextBox
' The various validating textboxes all inherit RegExTextBox
' which can varify that the contents of any TextBox match
' a regular expression.
Inherits SmartTextBox
' TextBox's numeric value
Protected mNumericValue As Double
Protected mFormatString As String
#Region " Windows Form Designer generated code "
Public Sub New()
MyBase.New()
'This call is required by the Windows Form Designer.
InitializeComponent()
'Add any initialization after the InitializeComponent() call
Me.ValidationExpression = "^\-?\d{1,}\.?\d{0,}$"
Me.ErrorMessage = "This number must be in the form of 12.345 (+ or -)"
Me.mFormatString = "F2"
End Sub
'UserControl overrides dispose to clean up the component list.
Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
If disposing Then
If Not (components Is Nothing) Then
components.Dispose()
End If
End If
MyBase.Dispose(disposing)
End Sub
'Required by the Windows Form Designer
Private components As System.ComponentModel.IContainer
'NOTE: The following procedure is required by the Windows Form Designer
'It can be modified using the Windows Form Designer.
'Do not modify it using the code editor.
<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
components = New System.ComponentModel.Container()
End Sub
#End Region
Public Overridable Property NumericValue() As Double
Get
Return mNumericValue
End Get
Set(ByVal Value As Double)
mNumericValue = Value
Me.Text = Format(Value, mFormatString) '.ToString
End Set
End Property
Public Property FormatString() As String
Get
Return mFormatString
End Get
Set(ByVal Value As String)
mFormatString = Value
End Set
End Property
Protected Overrides Sub OnValidated(ByVal e As System.EventArgs)
If Me.IsValid Then
Me.mNumericValue = Convert.ToDouble(Me.Text)
Else
Me.mNumericValue = Nothing
Me.Invalidate()
End If
' Any time you inherit a control, and override one of
' the On... subs, it's critical that you call the On...
' method of the base class, or the control won't fire
' events like it's supposed to.
MyBase.OnValidated(e)
End Sub
End Class
===========
Keith said:
I apologize for those of you who think I'm posting on the same topic. It
is not that I don't appreciate all of your comments - and I'm definitely
reading them all - but I think I have a differing opinion of how I want to
handle the 'user experience' in the application I'm creating. While I know
I could allow the user to enter in number and alpha text - in a text box -
and then tell them when the execuate a command "This is not numeric data", I
would rather not allow them to enter alpha data - to begin with.
I've posted the below code from a page someone suggested. It is from a
William Ryan. I have used it - it does work - but I run into two problems.
One, the user cannot use the backspace key and two, it allows someone to
enter another "." - decimal. The code author realizes this and says, "The
use above will allow all valid numbers as well as decimals. It wouldn't be
very difficult to expand upon this to verify that you don't have two decimal
in the number, allow for currency characters etc." However - to be quite
honest - I don't follow what the code is even doing. Can someone clarify
what it is doing and how one would modify it to allow for only one decimal?
(Bernie Yaeger I did read your post as well - if you could let me know how I
could download your code/control - I would love to see it) Please see
William's code below (link:
http://www.knowdotnet.com/articles/numerictextboxes.html)
Private Overloads Sub TextBox1_TextChanged(ByVal sender As System.Object,
ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles TextBox1.KeyPress