我的问题归结为:
我有六个TextBox,它们期望一个介于0和给定数字之间的值。 我想要实现的是:
这里的问题是,如果指定的数字是" 10",并且用户输入11,它将变为红色,但是,如果他们点击退格键(现在输入的数字) 1)数字保持红色,这不是预期的功能 - 数字1应该是黑色的,因为它在0和指定的数字之间。
所有指定的号码现在都是硬编码的(我在初学者课程中这只是我为了增加程序功能而做的事情而且我没有'我们已经为每个" Assignment"添加了课程,你可以从技术上输入负数,我现在不关心这个。
这是子程序,它被添加为某个GroupBox中所有文本框的处理程序
' Handler which gets added to all TextBoxes in "grpGrades" GroupBox
Private Sub txtGradePoints_TextChanged(sender As Object, e As EventArgs)
' Take in generic sender (Textbox) and convert to TextBox (necessary due to Strict mode)
Dim textBox = CType(sender, TextBox)
Try
' the value of the current TextBox being checked
Dim val = Decimal.Parse(textBox.Text)
Select Case textBox.Name
Case "txtPostPoints"
If val > 10 Then textBox.ForeColor = Color.Red
Case "txtCh1TestPoints", "txtCh2TestPoints", "txtCh3TestPoints"
If val > 50 Then textBox.ForeColor = Color.Red
Case "txtCh2TutPoints", "txtCh3TutPoints"
If val > 25 Then textBox.ForeColor = Color.Red
Case Else
textBox.ForeColor = Color.Black
End Select
Catch
textBox.ForeColor = SystemColors.ControlText
End Try
End Sub
这是onLoad Handler,它从" grpGrades"中获取相应的TextBox控件。 GroupBox并将上述TextChanged处理程序添加到每个处理程序。
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
' Get array of TextBox Controls from the "grpGrades" GroupBox
Dim textBoxes = grpGrades.Controls.OfType(Of TextBox)()
' Go through the array of TextBoxes and add the TextChanged handler to each TextChanged event
For Each txt In textBoxes
AddHandler txt.TextChanged, AddressOf txtGradePoints_TextChanged
Next
'AddHandler txtPostPoints.TextChanged, AddressOf txtGradePoints_TextChanged
'AddHandler txtCh1TestPoints.TextChanged, AddressOf txtGradePoints_TextChanged
'AddHandler txtCh2TestPoints.TextChanged, AddressOf txtGradePoints_TextChanged
'AddHandler txtCh3TestPoints.TextChanged, AddressOf txtGradePoints_TextChanged
'AddHandler txtCh2TutPoints.TextChanged, AddressOf txtGradePoints_TextChanged
'AddHandler txtCh3TutPoints.TextChanged, AddressOf txtGradePoints_TextChanged
End Sub
子例程的最后一部分只是注释掉的代码,是我最初添加处理程序的方式,以防我的新方法出现问题。
编辑:是否真的有必要进行投票?是什么原因?答案 0 :(得分:4)
您的代码从不测试有效值。将当前文本框设置为黑色的Case Else永远不会在当前文本框返回有效值时被点击。这不可能发生,因为Select Case将匹配文本框的当前名称,将再次测试无效值,然后退出Select Case块。您需要在当前文本框名称的相应Case中设置有效值的颜色。 IF conditional operator可以将所有内容减少到一行
Private Sub txtGradePoints_TextChanged(sender As Object, e As EventArgs)
' Take in generic sender (Textbox) and convert to TextBox (necessary due to Strict mode)
Dim textBox = CType(sender, TextBox)
Try
' the value of the current TextBox being checked
Dim val = Decimal.Parse(textBox.Text)
Select Case textBox.Name
Case "txtPostPoints"
textBox.ForeColor = IF(val > 10, Color.Red, Color.Black)
Case "txtCh1TestPoints", "txtCh2TestPoints", "txtCh3TestPoints"
textBox.ForeColor = IF(val > 50, Color.Red, Color.Black)
Case "txtCh2TutPoints", "txtCh3TutPoints"
textBox.ForeColor = IF(val > 25, Color.Red, Color.Black)
Case Else
' Not sure if it is needed for other textboxes....
textBox.ForeColor = Color.Black
End Select
Catch
textBox.ForeColor = SystemColors.ControlText
End Try
End Sub
答案 1 :(得分:2)
所以,正如其他人所说,你不会为每个文本框处理If
的两面。如果颜色符合条件,则设置颜色,但不反转颜色。
这是我处理这个问题的方法。它有点不同,但它将所有代码保存在一起,并且不需要任何Case
代码来计算调用文本框的名称。
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim check As Func(Of TextBox, Decimal, Boolean) =
Function(tb, d)
Dim value As Decimal
If (Decimal.TryParse(tb.Text, value)) Then
Return value > d
End If
Return False
End Function
Dim add As Action(Of TextBox, Decimal) =
Sub(tb, d)
AddHandler tb.TextChanged,
Sub(s, e2)
tb.ForeColor = If(check(tb, d), Color.Red, Color.Black)
End Sub
End Sub
add(txtPostPoints, 10)
add(txtCh1TestPoints, 50)
add(txtCh2TestPoints, 50)
add(txtCh3TestPoints, 50)
add(txtCh2TutPoints, 25)
add(txtCh3TutPoints, 25)
End Sub
因此,check
是一个Func(Of TextBox, Decimal, Boolean)
,它接受TextBox
并安全地解析其文本以查看它是否大于Decimal
值并返回True
如果是,那么False
。
而add
是一个Action(Of TextBox, Decimal)
,需要TextBox
和Decimal
并添加处理程序以调用check
将颜色设置为红色或黑色关于check
的结果。
为每个add
调用TextBox
非常简单。
所有硬编码都没有魔术字符串检查,所有这些都很好地封装在表单加载方法中。
答案 2 :(得分:1)
您正在使用基于名称的选择案例,唯一的条件是,如果它是> 10然后将前景变成红色。但你永远不会把它拒之门外。现在,在你提起案件之前,让我告诉你,其他情况只会基于textbox.name,因为找到了名字,否则其他人不会在这里玩。
因此,当找到名称时,请检查值> 10,并设置为红色,但如果不是,则不要告诉它该做什么。 10