【问题标题】:Detect the "sender" for Try...Catch检测 Try...Catch 的“发件人”
【发布时间】:2020-08-28 01:36:28
【问题描述】:

我有一个程序,我从不同的文本框中输入大量值,我使用try..catch 并检查 每个 textbox 仅用于输入数值。 如果我输入不同的字符,感谢Catch ex As System.InvalidCastException。 在此之后,我想更改出现错误的textbox 的背景颜色,例如ex.backcolor = color.red。我已经搜索过这个并尝试了很多东西,但我真的不知道如何处理这个变量。 感谢您的帮助,谢谢!

【问题讨论】:

    标签: vb.net try-catch


    【解决方案1】:

    根据您的描述,您几乎可以肯定做错了一些事情。我将提供一个完整的示例,但我将首先直接回答您的问题。你不需要“检测”任何东西。 sender 参数是您想要的对象。每个事件处理程序中的 sender 参数是引发事件的对象。这就是重点。如果您正在处理 TextBoxes 的事件,并且您想更改引发事件的 TextBoxBackColor,那么您可以通过 sender 参数访问该 TextBox,例如

    Dim tb = DirectCast(sender, TextBox)
    
    tb.BackColor = Color.Red
    

    在这种情况下进行验证的最佳方式取决于您的需要。不过,绝对没有理由抛出任何异常。首先,您需要决定是否要阻止用户离开包含无效输入的控件。如果你这样做了,那么你应该处理Validating 事件。您可以取消该事件以防止无效控件失去焦点。如果您不取消该事件,那么也会引发 Validated 事件,例如

    Imports System.ComponentModel
    
    Public Class Form1
    
        Private Sub TextBoxes_Validating(sender As Object, e As CancelEventArgs) Handles TextBox3.Validating,
                                                                                         TextBox2.Validating,
                                                                                         TextBox1.Validating
            Dim tb = DirectCast(sender, TextBox)
    
            'Check whether the control contains any non-numeric characters.
            If tb.Text.Any(Function(ch) Not Char.IsDigit(ch)) Then
                tb.BackColor = Color.Red
                tb.HideSelection = False
                tb.SelectAll()
    
                MessageBox.Show("Please enter only numeric characters.",
                                "Invalid Input",
                                MessageBoxButtons.OK,
                                MessageBoxIcon.Error)
    
                tb.HideSelection = True
                e.Cancel = True
            End If
        End Sub
    
        Private Sub TextBoxes_Validated(sender As Object, e As EventArgs) Handles TextBox3.Validated,
                                                                                  TextBox2.Validated,
                                                                                  TextBox1.Validated
            'If this event is raised then the control content is valid so reset the BackColor.
    
            Dim tb = DirectCast(sender, TextBox)
    
            tb.BackColor = SystemColors.Window
        End Sub
    
    End Class
    

    如您所见,这些方法处理多个控件的事件,并且代码专门引用引发事件的控件。当用户试图离开一个控件时,它的内容会被验证,如果他们因为无效而不能离开,就会通知用户。

    如果您希望让用户随意导航但使用BackColor 立即指示无效内容,则可以改为处理TextChanged 事件:

    Private Sub TextBoxes_TextChanged(sender As Object, e As EventArgs) Handles TextBox3.TextChanged,
                                                                                TextBox2.TextChanged,
                                                                                TextBox1.TextChanged
        Dim tb = DirectCast(sender, TextBox)
    
        tb.BackColor = If(tb.Text.Any(Function(ch) Not Char.IsDigit(ch)),
                          Color.Red,
                          SystemColors.Window)
    End Sub
    

    编辑:

    另一种选择是创建您自己的自定义控件并将功能直接构建到其中,因此您根本不必处理任何事件,例如

    Imports System.ComponentModel
    
    Public Class NumericTextBox
        Inherits TextBox
    
        <DefaultValue(GetType(Color), "Window")>
        Public Property NormalBackColor As Color = SystemColors.Window
    
        <DefaultValue(GetType(Color), "Red")>
        Public Property ErrorBackColor As Color = Color.Red
    
        Protected Overrides Sub OnTextChanged(e As EventArgs)
            MyBase.OnTextChanged(e)
    
            BackColor = If(Text.Any(Function(ch) Not Char.IsDigit(ch)),
                           ErrorBackColor,
                           NormalBackColor)
        End Sub
    
    End Class
    

    构建项目后,该控件将添加到工具箱窗口的顶部。然后,您可以将该控件添加到您的表单中,而不是常规的 TextBox 控件。无需任何额外代码,您就可以在这些控件中键入任何内容,如果您添加和删除非数字字符,它们会自动变为红色并再次变回。

    使用我添加的属性,您可以在设计器中选择两个可能的BackColor 值,就像选择其他属性一样。请注意,DefaultValue 属性使您能够右键单击工具箱中的这些属性并选择 重置 以将属性设置回指定的值。

    【讨论】:

    • 哦,我明白了,甚至不需要使用 try..catch 事件,只需发送者就足够了。真的很感激。非常感谢!
    • 哇,我不知道你能做到这一点,看起来很棒。一定要试一试。非常感谢您的回复。
    • 请注意,如果您在表单上已经有常规的TextBoxes,则不必删除它们并添加自己的NumericTextBoxes。您可以保留现有控件并更改其类型。不过,它需要手动编辑设计器代码,因此请务必先备份您的解决方案,以防万一您破坏它。在解决方案资源管理器中,单击 显示所有文件 按钮,展开您的表单并打开设计器代码文件。然后,您可以手动编辑对TextBox 类型的任何引用,以将它们更改为NumericTextBox。然后,您可以从表单中删除任何数字验证码。
    • 我不确定 OP 正在寻找什么类型的数字,但如果它不是整数,小数点不会弄乱.IsDigit 吗?他正在寻找的类型的.TryParse 可能有效。
    • @Mary,你是对的。我确实提到了有多种可能的选择,因此我的代码就是一个例子。我选择了我所做的选项,因为它允许在没有额外条件的情况下使用空控件,但它肯定不会涵盖所有可能性。我对展示验证所涉及的原则更感兴趣。 OP 当然可能需要调整细节。
    猜你喜欢
    • 1970-01-01
    • 2022-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-23
    • 1970-01-01
    • 2019-08-06
    • 1970-01-01
    相关资源
    最近更新 更多