如何防止System.Windows.Forms.NumericUpDown允许在DecimalPlaces = 0时键入非数字?

时间:2010-12-03 22:41:46

标签: winforms .net-4.0 validation numericupdown decimal-point

我希望这个WinForm控件(NumericUpDown)有条件地强制执行整数,具体取决于我正在处理的事物的类型(整体与浮动)。

如果我设置DecimalPlaces = 0,它会显示0,然后当我单击向上/向下时将其递增/递减1。但是,如果我输入0.6,则会显示为1,但仍会保留为0.6。如果我随后递增它,则基础但未显示的值将为1.6。

我正在寻找一种简单,惯用的方式来强制执行我想要的东西(希望很明显我想要的东西)。如果我必须截取某种事件,那么我会,但我希望只依赖NumericUpDown类已经提供的一些标志/设置。

如果您的解决方案涉及子类NumericUpDown,那么我将不得不考虑这一点。在发布的这个阶段,我更希望有一个记录良好的hack来进行干净的更改,这可能会导致其他地方的错误。我想选择不对NumericUpDown进行细分。

如果您有任何问题,请告诉我,谢谢。

2 个答案:

答案 0 :(得分:1)

基础值为十进制类型。 DecimalPlaces仅影响控件中显示的位数。实现所需目标的最简单方法是将NumericUpDown.Value舍入为int。

答案 1 :(得分:0)

这是我们正在使用的不完美解决方案。首先,防止用户键入小数(用户可能键入的其他所有内容似乎都由控件本身处理):

Private Sub HandleKeyPress(sender As Object, e As Windows.Forms.KeyPressEventArgs) Handles MyNumericUpDown.KeyPress
   If e.KeyChar = "."c Then e.Handled = True
End Sub

其次,防止用户粘贴除数字以外的任何内容。请注意,我采用的方法硬编码了几个特定的​​键组合(ctrl-v和shift-insert)。它不会处理用户可能粘贴的其他方式,例如使用上下控制的上下文菜单。

Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, 
                                           ByVal keyData As System.Windows.Forms.Keys) As Boolean
  If keyData = (Keys.Shift Or Keys.Insert) OrElse keyData = (Keys.Control Or Keys.V) Then
     Dim data As IDataObject = Clipboard.GetDataObject
     If data Is Nothing Then
        Return MyBase.ProcessCmdKey(msg, keyData)
     Else
        Dim text As String = CStr(data.GetData(DataFormats.StringFormat, True))
        If text = String.Empty Then
           Return MyBase.ProcessCmdKey(msg, keyData)
        Else
           For Each ch As Char In text
              If Not Char.IsNumber(ch) Then
                 Return True
              End If
           Next
           Return MyBase.ProcessCmdKey(msg, keyData)
        End If
     End If
  Else
     Return MyBase.ProcessCmdKey(msg, keyData)
  End If
End Function

这不是一个完美的解决方案,但它足以满足我们的需求。