TextBoxes that accept only numbers

  • Thread starter Thread starter Woody Splawn
  • Start date Start date
W

Woody Splawn

We have access to Infragistics etc., but we would like to make use of a
regular VS textbox so that it accepts only numbers. We have discovered that
if you bind an integer field to a textbox, for example, the textbox will
only accept numbers. This is nice but what do you do about nulls? It does
not seem to accept nulls. What do you do about literals? (like commas in
100,000). Is there a white paper somwhere that delineates all the issues?
Is there a custom control already written somewhere that we could take
advantage of?

Any pointers, comments or suggestions appreciated.
 
Hi Woody,

I've actually written a control for this purpose (I wrote a different, but
similar, one for currency only). Below is the code. Once you build the
solution, you have to add the control in the usual way to vs .net. Then you
may need some help as to why I created 2 new events - leavex and keypressx,
and if you do, just email me back with any questions at
(e-mail address removed).

I can send you the .dll itself, but this actually should be easier, as the
code is pretty brief and straightforward. Moreover, you can modify it to
accept commas, as I did not include that.

Bernie Yaeger
Imports System.ComponentModel

Public Class textboxnumbersonly

Inherits System.Windows.Forms.TextBox

Public Event leavex()

Public Event keypressx(ByVal e As System.Windows.Forms.KeyPressEventArgs)

Sub New()

MyBase.New()

Me.Text = "0"

Me.TextAlign = System.Windows.Forms.HorizontalAlignment.Right

End Sub

Protected Overrides Sub OnKeyPress(ByVal e As
System.Windows.Forms.KeyPressEventArgs)

Dim KeyAscii As Integer = Asc(e.KeyChar)

If Me.Text.Length > 0 And KeyAscii = 45 And Me.SelectionStart <> 0 Then

e.Handled = True

RaiseEvent keypressx(e)

Exit Sub

End If

If InStr(Me.Text, "-") And KeyAscii = 45 Then

e.Handled = True

RaiseEvent keypressx(e)

Exit Sub

End If

Select Case KeyAscii

Case 48 To 57, 45, 8, 27, 9 ' 46 is . 45 is - 43 is + 8 is backspace

' 27 is escape; delete, arrow keys, home, end are not trapped

' by keypress so they are available

Case Else

KeyAscii = 0

End Select

If KeyAscii = 0 Then

e.Handled = True

Else

e.Handled = False

End If

RaiseEvent keypressx(e)

End Sub

Protected Overrides Sub OnLeave(ByVal e As System.EventArgs)

If Me.Text = "-" Or Me.Text.Length = 0 Then

Me.Text = "0"

End If

RaiseEvent leavex()

End Sub

End Class
 
Bernie Yaeger said:
I can send you the .dll itself, but this actually should be easier, as the
code is pretty brief and straightforward. Moreover, you can modify it to
accept commas, as I did not include that.

What do you do about pasting in text from the clipboard?

LFS
 
Thank you for your input.

Did you see the part in my message regarding nulls? How do you deal with
nulls?
 
Hi Larry,

That's why I have a leavex event - on leave, if the text does not covert to
a number, it can be reset to zero.

Bernie
 
Hi Woody,

I did see that comment, but I kind of glossed over it. I assume the textbox
is filled by a person entering keystrokes. If this is so, then you can
leave it blank when the data should be null, mark it blank in the leavex
event, and deal with that accordingly (blank diff from 0). If however the
data is posted from a datalink, you should be able to code the textbox.text
to display blank if isdbnull. So I don't see the issue, frankly.

HTH,

Bernie
 
Well here goes another class... it take care of some regional settings, and
it will also check for clipboard events.

Best wishes.


Public Class NumericTextBox
Inherits System.Windows.Forms.TextBox

Private str_OldText As String
Private int_SelectionStart As Integer
Private int_SelectionLength As Integer

Public Sub New()
MyBase.New()
Me.str_OldText = Nothing

If
(System.Globalization.NumberFormatInfo.CurrentInfo.NegativeSign.Length <> 1)
Or (System.Globalization.NumberFormatInfo.CurrentInfo.NumberDecimalSeparator
<> 1) Then
Throw New Exception("This class can't be used with your current
regional settings.")
End If
End Sub

Public Overrides Property Text() As String
Get
Return MyBase.Text
End Get
Set(ByVal Value As String)
If Not IsNumeric(Value) Then
Beep()
MyBase.Text = ""
Else
MyBase.Text = Value
End If
End Set
End Property

Protected Overrides Sub OnKeyDown(ByVal e As
System.Windows.Forms.KeyEventArgs)
If (e.Shift) And (e.KeyCode = Keys.Insert) Then
If Clipboard.GetDataObject.GetDataPresent(DataFormats.Text) Then
If Not
IsNumeric(Clipboard.GetDataObject.GetData(DataFormats.Text)) Then
Beep()
e.Handled = True
End If
Else
Beep()
e.Handled = True
End If
End If
End Sub

Protected Overrides Sub OnKeyPress(ByVal e As
System.Windows.Forms.KeyPressEventArgs)
If Not Char.IsControl(e.KeyChar) Then
If Not Char.IsDigit(e.KeyChar) Then
Select Case e.KeyChar
Case
System.Globalization.NumberFormatInfo.CurrentInfo.NumberDecimalSeparator
If InStr(Me.Text,
System.Globalization.NumberFormatInfo.CurrentInfo.NumberDecimalSeparator)
Then
Beep()
e.Handled = True
ElseIf Me.SelectionStart = 0 Then
If Me.SelectionLength = Me.Text.Length Then
Me.Text = "0" &
System.Globalization.NumberFormatInfo.CurrentInfo.NumberDecimalSeparator
Me.SelectionStart = 2
e.Handled = True
Else
Me.Text = "0" &
System.Globalization.NumberFormatInfo.CurrentInfo.NumberDecimalSeparator &
Me.Text.Substring(Me.SelectionLength)
Me.SelectionStart = 2
e.Handled = True
End If
End If
Case
System.Globalization.NumberFormatInfo.CurrentInfo.NegativeSign
If Me.SelectionStart = 0 Then
If Me.Text.Length > 0 Then
If Me.Text.Substring(0, 1) =
System.Globalization.NumberFormatInfo.CurrentInfo.NegativeSign Then
Beep()
e.Handled = True
End If
End If
Else
Beep()
e.Handled = True
End If
Case Else
Beep()
e.Handled = True
End Select
End If
End If
End Sub

Protected Overrides Sub OnMouseDown(ByVal e As
System.Windows.Forms.MouseEventArgs)
Me.str_OldText = Me.Text
Me.int_SelectionStart = Me.SelectionStart
Me.int_SelectionLength = Me.SelectionLength
End Sub

Protected Overrides Sub OnMouseUp(ByVal mevent As
System.Windows.Forms.MouseEventArgs)
If Not IsNumeric(Me.Text) Then
Me.Text = Me.str_OldText
Me.SelectionStart = Me.int_SelectionStart
Me.SelectionLength = Me.int_SelectionLength
End If

Me.str_OldText = Nothing
Me.Refresh()
End Sub

Protected Overrides Sub OnPaint(ByVal e As
System.Windows.Forms.PaintEventArgs)
If Me.str_OldText Is Nothing Then
MyBase.OnPaint(e)
End If
End Sub
End Class
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top