Range Providers
The IntegerRangeProvider is also useful for validating user values entered into TextBoxes. This extender provides two properties:
MinValue and
MaxValue. It catches a TextBox's
Validating event and determines whether the TextBox contains an integer value between
MinValue and
MaxValue. If the value is not an integer or falls outside of this range, IntegerRangeProvider displays an ErrorProvider with an appropriate message.
Figure 2 shows an IntegerRangeProvider that validates three TextBoxes. The first TextBox contains a value that is within its allowed range, but the second and third TextBoxes hold values that are out of bounds. In Figure 2, the mouse is hovering over the second TextBox's ErrorProvider so its message is visible.
 | |
Figure 2. IntegerRangeProvider: This class uses an ErrorProvider component to display error messages if a TextBox's value is out of bounds. |
The main difference between IntegerRangeProvider and the previous providers is that it uses an ErrorProvider to display its messages. IntegerRangeProvider inherits from Component so you can put one on a form. If you double-click a component in the Solution Explorer, Visual Studio opens it in a graphic designer. You can then drag tools from the Toolbox and drop them on this designer to add them to the Component.
When you drag a tool onto the Component, Visual Studio adds appropriate code to the Component to support the tool. The following code shows how Visual Studio supports the ErrorProvider added to the IntegerRangeProvider. The code creates a container for the provider's Components and makes an InitializeComponent method to create the container, it builds the ErrorProvider, adds it to the container, and initializes the ErrorProvider.
Private components As System.ComponentModel.IContainer
Friend WithEvents errMessage As System.Windows.Forms.ErrorProvider
Private Sub InitializeComponent()
Me.components = New System.ComponentModel.Container
Me.errMessage = New _
System.Windows.Forms.ErrorProvider(Me.components)
CType(Me.errMessage, _
System.ComponentModel.ISupportInitialize).BeginInit()
CType(Me.errMessage, _
System.ComponentModel.ISupportInitialize).EndInit()
End Sub
Unfortunately the
InitializeComponent subroutine isn't actually called anywhere, so you need to give the provider a constructor that does call it. The following code shows the IntegerRangeProvider's constructor:
Public Sub New()
InitializeComponent()
End Sub
Now when the provider needs to display an error message, it simply calls the ErrorProvider's
SetError method to give a TextBox an error message.
The code below shows how the IntegerRangeProvider class validates the contents of a TextBox. If the TextBox contains no text, the provider sets its msg variable to an empty string. Otherwise, if the TextBox contains a non-numeric value, the code sets msg to the message "Value is not numeric."
If the TextBox contains a non-blank, numeric value, the provider converts it into an integer and compares it to the TextBox's MinValue and MaxValue properties. If the value is out of range, the code sets msg to an appropriate message. If the value checks out okay, the code sets msg to a blank string.
Finally, the code uses the ErrorProvider's SetError method to set the TextBox's error message appropriately.
' See if the value is between the min and max value.
Private Sub Extendee_Validating(ByVal sender As Object, _
ByVal e As System.ComponentModel.CancelEventArgs)
Dim extendee As TextBox = DirectCast(sender, TextBox)
Dim msg As String = ""
If extendee.Text.Trim.Length = 0 Then
msg = ""
ElseIf Not IsNumeric(extendee.Text) Then
msg = "Value is not numeric"
Else
Try
Dim value As Integer = Integer.Parse(extendee.Text)
Dim min_value As Integer = GetMinValue(extendee)
If value < min_value Then
msg = "Value is less than " & min_value
Else
Dim max_value As Integer = GetMaxValue(extendee)
If value > max_value Then
msg = "Value is greater than " & max_value
End If
End If
Catch ex As Exception
msg = ex.Message
End Try
End If
errMessage.SetError(extendee, msg)
End Sub
Provident Providers
Often a control does
almostbut not quite
exactlywhat you need. You can make a new control derived from the almost perfect one and modify it, but that's a lot of work and can give you some very complicated code to maintain.
ExtenderProviders give you a useful alternative. They let you add new properties to existing components, let you catch a component's events, and take appropriate actions. By deriving an ExtenderProvider from an existing control (such as Label) or by including an existing component (such as ErrorProvider) inside the provider, you can essentially add new behaviors to existing classes. Now if only the same worked in day-to-day life. I wouldn't mind adding new behaviors to traffic lights, parking meters, politicians, the Internal Revenue Service, and a few others.