在WinForms中处理无效输入数据的最佳方法是什么?

lvmkulzt  于 2022-11-17  发布在  其他
关注(0)|答案(1)|浏览(139)

我制作了一个表单,用户可以在其中动态地生成一个客户订单,该订单包含一个或多个订单位置。对于每个位置,都有几个属性,如金额、产品名称、价格、折扣等。
我的主要问题是:处理输入字段无效值的最佳方法是什么?例如,如果用户在金额字段中键入“X”,而不是1、2或其他值。基本思想是让用户输入他们想要的任何内容-但订单只能在每个输入字段包含有效数据时保存。如果不是,所有无效字段将突出显示,以便用户知道他做错了什么。
到目前为止,这看起来还不错,但我的想法是,也有一个Customer_Order对象,它将在用户每次更改输入字段的值时更新。显然,如果我想允许用户在Integer或Decimal字段中输入字符串(如“X”),我无法做到这一点......因此,在我看来,我有两种选择:
答:要么限制输入字段,要么以编程方式将无效值转换为零(例如:用户在价格字段中输入“abc”-〉字符串将转换为0,00)或B:我保留了我的原始计划,没有那么严格的输入规则,也没有一个总是保持最新的Customer_Order对象。相反,我会从头开始创建该对象,并在用户完成订单时用输入字段中的所有数据填充它。
我对A的问题是,我希望输入字段尽可能地不严格。如果用户键入了无效的内容,他们应该看到他们键入的内容,而不是程序更改值。我对B的问题是,拥有一个始终最新的客户订单对象使计算价格变得更容易。如果我没有该对象,每当我想计算一些东西时,我必须读出并解析所有必要的输入字段。
我对GUI不是很有经验,所以我真的不知道我是否错过了什么......处理这个问题的最优雅的方法是什么?在后台始终保持一个总是最新的对象通常是个坏主意吗?

px9o7tmv

px9o7tmv1#

一个选项是只允许有效的密钥,这可以通过使用KeyDown事件处理程序来实现。

建立新的Windows Forms App (.NET Framework)项目
向表单中添加一个TextBox(名称:文本框金额)
开启方案总管

  • 在VS菜单中,单击查看

  • 选取方案总管
    打开属性窗口

  • 在VS菜单中,单击查看

  • 选择属性窗口
    添加TextBox KeyDown事件处理程序

  • 在“属性”窗口中,从下拉列表中选择“textBoxAmount

  • 单击

  • 双击KeyDown
    添加模块(名称:帮助程序输入.vb)

  • 单击项目

  • 选择添加模块...(名称:帮助程序输入.vb)

  • 单击确定
    帮助程序输入.vb

Imports System.Globalization

Module HelperInput
    Public Sub TBKeyDownMonetaryValue(sender As Object, e As System.Windows.Forms.KeyEventArgs)
        Dim tb As Control = DirectCast(sender, Control) 'TextBox

        Dim isKeyAllowed As Boolean = False

        Dim nfInfo As NumberFormatInfo = CultureInfo.CurrentUICulture.NumberFormat
        Debug.WriteLine($"currency symbol: {nfInfo.CurrencySymbol} decimal separator: {nfInfo.CurrencyDecimalSeparator} number group separator: {nfInfo.NumberGroupSeparator} currency group separator: {nfInfo.CurrencyGroupSeparator}")

        If Not Control.ModifierKeys = Keys.Shift Then
            Select Case e.KeyCode
                Case Keys.Enter
                    isKeyAllowed = True
                Case Keys.Back
                    isKeyAllowed = True
                Case Keys.Delete
                    isKeyAllowed = True
                Case Keys.NumPad0
                    isKeyAllowed = True
                Case Keys.NumPad1
                    isKeyAllowed = True
                Case Keys.NumPad2
                    isKeyAllowed = True
                Case Keys.NumPad3
                    isKeyAllowed = True
                Case Keys.NumPad4
                    isKeyAllowed = True
                Case Keys.NumPad5
                    isKeyAllowed = True
                Case Keys.NumPad6
                    isKeyAllowed = True
                Case Keys.NumPad7
                    isKeyAllowed = True
                Case Keys.NumPad8
                    isKeyAllowed = True
                Case Keys.NumPad9
                    isKeyAllowed = True
                Case Keys.D0
                    isKeyAllowed = True
                Case Keys.D1
                    isKeyAllowed = True
                Case Keys.D2
                    isKeyAllowed = True
                Case Keys.D3
                    isKeyAllowed = True
                Case Keys.D4
                    isKeyAllowed = True
                Case Keys.D5
                    isKeyAllowed = True
                Case Keys.D6
                    isKeyAllowed = True
                Case Keys.D7
                    isKeyAllowed = True
                Case Keys.D8
                    isKeyAllowed = True
                Case Keys.D9
                    isKeyAllowed = True
                Case Else
                    isKeyAllowed = False
            End Select
        End If

        'only allow one currency decimal separator
        If e.KeyCode = Keys.Oemcomma AndAlso nfInfo.CurrencyDecimalSeparator = "," AndAlso (String.IsNullOrEmpty(tb.Text) OrElse Not tb.Text.Contains(nfInfo.CurrencyDecimalSeparator)) Then
            isKeyAllowed = True
        ElseIf e.KeyCode = Keys.OemPeriod AndAlso nfInfo.CurrencyDecimalSeparator = "." AndAlso (String.IsNullOrEmpty(tb.Text) OrElse Not tb.Text.Contains(nfInfo.CurrencyDecimalSeparator)) Then
            isKeyAllowed = True
        End If

        If Not isKeyAllowed Then
            e.Handled = True
            e.SuppressKeyPress = True
        End If
    End Sub
End Module

表单1.vb

Public Class Form1
    Private Sub TextBoxAmount_KeyDown(sender As Object, e As KeyEventArgs) Handles TextBoxAmount.KeyDown
        HelperInput.TBKeyDownMonetaryValue(sender, e)
    End Sub
End Class

资源

相关问题