Google
WWW Yariv Hammer's Code Site

Monday, October 24, 2005

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 &amp; " 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

Feel free to use everything here. Add links to my site if you wish.

Do not copy anything to other sites without adding link to here.

All the contents of the site belong to Yariv Hammer.