【问题标题】:Check for Negative Input in Textbox检查文本框中的否定输入
【发布时间】:2020-12-26 08:31:13
【问题描述】:

我正在尝试验证 Windows 窗体应用程序中的文本框。文本框接受任何数字(它应该是小数,但也接受整数)。我不希望该数字为负数,但即使在添加 if 语句之后,即使输入的数字是否定的,应用程序仍然接受它。我不确定我做错了什么。

try
{
    //Different operations being done here that use the input from txtEnterTotal.Text 
}
catch
{
    decimal entertotal = Convert.ToDecimal(txtEnterTotal.Text);
    if (entertotal <= 0)
    {
        MessageBox.Show("Please enter a valid number for the total field.", "Entry Error");
    }
}

我也试过了

catch
            {

                if (decimal.TryParse(txtEnterSubtotal.Text, out decimal value))
                {
                    if (value < 0)
                    {

                        MessageBox.Show("Please enter a valid number for the Subtotal field.", "Entry Error");
                    }
                    else
                    {
                        MessageBox.Show("thank you");
                    }
                }

            }

我发现发布了一个类似的问题,但它使用的是我尚未学过的另一种语言,但由于它仍然询问相同的问题,我尝试了一些发布的答案,但我仍然遇到问题。 链接:How do you check if an input is a negative number in VB

注意:我只想使用 try catch 语句来执行此操作。

【问题讨论】:

  • 考虑使用Decimal.TryParse() 而不是try-catch。后者通常不应用于正常的程序流程。此外,Convert.ToDecimal 可以反过来抛出异常,而xxx.TryParse() 则不会
  • 您只检查负数如果有异常 - 也就是说,在try/catch 语句的catch 代码块中 - 可能没有异常,取决于try 代码块中发生的情况。一般来说,您根本不需要try/catch - 请参阅@MickyD 在先前评论中的建议。
  • 该链接中的代码有什么问题,它使用 .Net 方法。在 C# 中,您具有可以内联输出变量的优势:例如if (decimal.TryParse(txtEnterTotal.Text, out decimal value)) { if (value &lt; 0) { /* Negative value */ } } else { /* Not a valid value */ }
  • 我更新了我的代码并尝试过,但我的应用程序仍然接受它并进行所有计算,尽管@Jimi 是负数
  • Convert.ToDecimal(txtEnterTotal.Text) 将在 txtEnterTotal.Text 不是有效数字时抛出异常。可能不希望在您的 catch 块中...

标签: c# winforms validation input


【解决方案1】:

示例代码的一个问题是您在catch 块中执行Convert.ToDecimal(txtEnterTotal.Text),但如果txtEnterTotal.Text 不是有效数字,这将引发异常,因此现在将未处理异常。

既然你说你真的想使用try/catch 来验证文本框,那么基本模式是尝试转换try 块中的数字,如果失败,采取行动(那不会' t 抛出另一个异常)在 catch 块中。

例如:

private void btnValidate_Click(object sender, EventArgs e)
{
    try
    {
        // Here we perform the operation that might throw an exception
        decimal value = Convert.ToDecimal(txtEnterSubtotal.Text);

        // If we get here, no exception was thrown
        MessageBox.Show("Thank you");
    }
    catch
    {
        // Since there was an exception, show a message and clear the textbox
        MessageBox.Show("Please enter a valid, positive number");
        txtEnterSubtotal.Clear();
        txtEnterSubtotal.Focus();
    }
}

但是,使用 try/catch 进行简单的错误处理是“昂贵的”(捕获调用堆栈是有代价的),而且这也不是它们的预期目的(它们应该用于异常事件,而不是正常程序流程的控制)。

这是了解数字类型所具有的TryParse 方法的好时机。该方法接受string 进行解析,如果成功,则将数字类型的out 参数设置为转换后的值。最好的部分是它返回一个表示成功的bool,因此我们可以在if 条件下使用它,并在字符串解析失败时采取一些措施。

例如,您可以在不再需要try/catch 的验证方法中包含此代码,因为我们改为使用TryParse 进行验证:

private void btnValidate_Click(object sender, EventArgs e)
{
    // Here we check if `TryParse` does NOT return true (note the exclamation mark), OR
    // if the converted number less than zero, where in either case we take some action
    if (!decimal.TryParse(txtEnterSubtotal.Text, out decimal value) ||
        value < 0)
    {
        // Show a message, then clear the textbox
        MessageBox.Show("Please enter a valid, positive number");
        txtEnterSubtotal.Clear();
        txtEnterSubtotal.Focus();
    }
    else
    {
        MessageBox.Show("Thank you");
    }
}

【讨论】:

    【解决方案2】:

    我认为验证您的输入是否为数字和小数的最佳方法是使用如下代码。作为评论者,@MickyD 建议,Decimal.TryParse 像这样:

    try
    {
        //Different operations being done here that use the input from txtEnterTotal.Text 
    }
    catch(Exception ex)
    {
        // catch the exception and DO something with it.
        System.Diagnostics.Trace.TraceError("Error before try/parse: {0}", ex);
        //decimal entertotal = Convert.ToDecimal(txtEnterTotal.Text);
        // old code ^^^^^^
        // new code 
        if (decimal.TryParse(txtEnterTotal.Text, out decimal entertotal))
        {
            if (entertotal <= decimal.Zero)
            {
                MessageBox.Show("Please enter a valid number for the total field.", "Entry Error");
            }
        } 
        else 
        {
            MessageBox.Show(string.Format("Failed to parse value: {0}", txtEnterTotal.Text));
        }
    }
    

    【讨论】:

    • catch 块中的代码在做什么?您有 在此处使用来自 txtEnterTotal.Text 的输入的不同操作 在那里完成,这就是需要在 TextBox 中输入的值的地方。如果不用于其他用途,则应删除 try/catch 块。但这与 TextBox.Text 的验证无关。
    • @Jimi 同意,那里应该有一个异常实例,我们应该对它做点什么。-- 我只是从用户的示例代码开始工作,并专注于手头的 Decimal.Parse 问题跨度>
    • @GlennFerrie 我尝试了你所拥有的,它可以工作,但是当我点击我的计算按钮时,它第一次被接受,如果我再次点击它,我就会收到消息。它似乎没有第一次抓住它
    • 这不是关于catch 部分的语法,而是关于.TryParse() 的使用。不再需要 try/catch 块,这就是 TryParse() 的意义所在。
    • @rythm500 “这就是我的教科书所说的使用” - 我会得到一本不同的教科书;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-19
    • 1970-01-01
    相关资源
    最近更新 更多