Decimal.TryParse在TextBox.Leave和TextBox.LostFocus上失败

时间:2010-12-22 16:44:59

标签: vb.net winforms .net-3.5 textbox decimal

这一直是我遇到的最令人沮丧的愚蠢错误之一,我只是想看看其他人是否曾遇到此问题。

这是交易。我在VB 2008(.NET 3.5)中的Windows窗体应用程序中有一个TextBox,用户可以在其中键入估计数量。我允许他们兑换美元和美分,我想要四舍五入到最接近的美元。原始代码在将数据写回表时进行了舍入,并且运行正常 - 我将此代码放在“保存”例程中,当用户移动到不同的屏幕或记录时触发该例程:

    Dim est As Decimal : Decimal.TryParse(txtEstimateAmount.Text.Trim, est)
    Dim estimatedAmount As Integer = Math.Round(est)

我决定,一旦他们离开现场实际进行舍入可能会很好,所以当他们重新加载屏幕并发现1822.60现在是1823时他们并不感到惊讶。所以我采用完全相同的代码并将其添加到TextBox.Leave事件处理程序中。最奇怪的事情发生了:在解析之后,用1822.60填充变量 \ test ,而不是变量设置为-1!什么......?

调试处理程序会显示该值正确进入解析器,如果我通过Immediate窗口手动解析,它会正确解析,但是当我让代码执行时,它总是设置为-1。甚至更奇怪的是任何数字被解析为-1,而不仅仅是小数,而任何非数字都被解析为0(这是正确的)。

有没有其他人遇到此事?我尝试将代码移动到TextBox.LostFocus事件,但结果相同。我不知道到底发生了什么,显然有很多变通方法,但它没有任何意义。

编辑:这是完整的事件处理程序(当前行为是在TextBox中放置-1):

Private Sub txtEstimateAmount_Leave(ByVal sender As Object, ByVal e As System.EventArgs) Handles txtEstimateAmount.Leave
    ' Take any dollars-and-cents amount and round to the nearest dollar
    Dim est As Decimal
    est = Decimal.TryParse(txtEstimateAmount.Text.Trim, est)
    txtEstimateAmount.Text = If(est <> 0, Math.Round(est).ToString(), String.Empty)
End Sub

2 个答案:

答案 0 :(得分:5)

首先,您确实需要使用Validating事件处理程序执行此操作,以便您可以捕获垃圾并避免忽略TryParse的返回值。像这样:

Private Sub TextBox1_Validating(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles TextBox1.Validating
    Dim est As Decimal
    If TextBox1.Text.Length = 0 then Exit Sub   '' optional
    If Not Decimal.TryParse(TextBox1.Text.Trim, est) Then
        e.Cancel = True
        TextBox1.SelectAll()
    Else
        TextBox1.Text = est.ToString("N0")
    End If
End Sub

解释-1很困难。如果TryParse无法解析文本,则通常会写入0。注意更改UI线程的CurrentCulture属性。以及对“控制面板+区域和语言”小程序中的格式设置所做的任何更改。

答案 1 :(得分:2)

我认为您发布的代码不是您正在运行的代码。发生的事情是:

Dim est As Decimal = Decimal.TryParse(txtEstimateAmount.Text.Trim, est)     
Dim estimatedAmount As Integer = Math.Round(est) 

我会做一个干净的重建或尝试用不同的格式重写它,也许用布尔值来获得tryparse的结果。

编辑,我已经看到了你的实际代码。您确实将tryparse结果中的true / false放入了est十进制数。删除est =。 Est被加载,因为它通过引用传递给tryparse。