Problems With NumericUpDown Control and Binding
Introduction
The NumericUpDown control has some problems in .NET 2003, which I will show how to solve:
- When the user edit the NumericUpDown and deletes the content of the TextBox, leaving it empty, an unhandled exception will be shown when the control looses focus.
- When the control is bound to a DataTable, and the user edits the text (not pressing on the up and down buttons), the changed value is not updated to the table when the control looses focus as expected.
I will also show how to show a MessageBox notifying the user that the value he inserted is not valid, and the valid range. After the message is gone the user will not be able to exit the control.
The Code
We will need to inherit from NumericUpDown, and add the following code to the new control (The code is in VB.NET):
-----------------------------------------------------
Public Class MyNumericUpDown
Inherits System.Windows.Forms.NumericUpDown
(...) ' Windows designer stuff
Private bHaveChanges As Boolean = False
Protected Overrides Sub OnKeyPress(ByVal e As System.Windows.Forms.KeyPressEventArgs)
bHaveChanges = True
End Sub
Private Sub RefreshValue()
Dim oldMax As Decimal = Me.Maximum
Me.Maximum += Me.Increment*2
Me.UpButton()
Me.DownButton()
Me.Maximum = oldMax
End Sub
Private _lock As Boolean = False
Private Sub IosNumericUpDown_LostFocus(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.LostFocus
If _lock Then Exit Sub
If (Me.Text = "") Then
_lock = True
Me.Text = "0"
_lock = False
End If
Try
If CDec(Me.Text) <> Me.Maximum Then
_lock = True
MsgBox("Value should be between " & Me.Minimum & " and " & Me.Maximum & "!", _
MsgBoxStyle.OKOnly + MsgBoxStyle.Critical, "Validation")
Me.Focus()
Me.Select(0, Me.Text.Length)
_lock = False
Return
End If
Catch ' CDbl failed
_lock = False
Me.Text = "0"
End Try
If bHaveChanges Then
RefreshValue()
bHaveChanges = False
End If
End Sub
Private Sub IosNumericUpDown_Leave(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Leave
If Value = _beforeValue Then Exit Sub
_lockEnterLeave = True
RefreshValue()
_lockEnterLeave = False
End Sub
Private _lockEnterLeave As Boolean = False
Private _beforeValue As Decimal
Private Sub IosNumericUpDown_Enter(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Enter
If _lockEnterLeave Then
Exit Sub
End If
_beforeValue = Value
End Sub
End Class
-----------------------------------------
0 Comments:
Post a Comment
<< Home