完全披露,我正在为COP2170进行任务,但附加功能并不仅仅是为了进一步扩展......
我试图添加5个测试分数并输出5个分数的平均值,该部分工作得很好。此外,我试图添加一个允许用户输入少于5分的附加功能,程序仍然会输出输入的任何分数的平均值。
这样可行:
这有效:
我遇到的问题是,如果省略第一个分数并填写其余分数,则不起作用:
这是我到目前为止所获得的代码:
Public Class frmTestScoreAverage
Private Sub btnCalculate_Click(sender As Object, e As EventArgs) Handles btnCalculate.Click
Dim decScore1, decScore2, decScore3, decScore4, decScore5 As Double ' decScore1-5 to hold test scores1-5
Dim decScoreAverage As Double ' to hold test score average
Dim intDivideBy As Double = 5 ' declare intDivideBy variable with starting value of 5
lblStatusLabel.Text = String.Empty 'set error message to empty string
Try
' Read user input convert to double and assign value to variable
decScore1 = Convert.ToDouble(txtScore1.Text)
decScore2 = Convert.ToDouble(txtScore2.Text)
decScore3 = Convert.ToDouble(txtScore3.Text)
decScore4 = Convert.ToDouble(txtScore4.Text)
decScore5 = Convert.ToDouble(txtScore5.Text)
' Calculate average
decScoreAverage = (decScore1 + decScore2 + decScore3 + decScore4 + decScore5) / intDivideBy
'display result
lblResult.Text = CStr(decScoreAverage)
Catch
' Display error message, asks for all scores
lblStatusLabel.Text = "Please enter all test scores"
'Calculate average even without all scores
For Each c As TextBox In Me.Controls.OfType(Of TextBox)() 'loop through each textbox in form see: http://stackoverflow.com/a/13504361/1947286
If c.Text = String.Empty Then intDivideBy -= 1 'If text equals empty string, Then decrement intDivideBy
Next
'catch divide by zero error
Try
'calculate average
decScoreAverage = (decScore1 + decScore2 + decScore3 + decScore4 + decScore5) / intDivideBy 'add test scores and divide to find average
'display result
lblResult.Text = CStr(decScoreAverage)
Catch
lblStatusLabel.Text = "Please enter at least one test score"
End Try
End Try
End Sub
End Class
我很确定问题与我找到平均值的方式有关:
decScoreAverage = (decScore1 + decScore2 + decScore3 + decScore4 + decScore5) / intDivideBy
有没有办法找到任何排列中允许空变量的平均值?
答案 0 :(得分:2)
你遇到的问题是Convert.ToDouble(txtBox.text)(带有空字符串,会使Convert抛出异常。
添加字符串不为空的验证或使用TryParse查看Textbox值是否可解析为数字。
无论
If not String.IsNullOrEmpty(txtBox.Text) then
Convert.ToDouble(txtBox.text)
或者
dim value as Double
if Double.TryParse(txtBox.Text, value) then
avg += value
当第一个为空时,它转到代码的Catch部分,然后你尝试计算平均值,但是Txtbox的值没有分配给你做的声明,所以当它试图做平均
decScore1 = Convert.ToDouble(txtScore1.Text) // Exception here to Catch
decScore2 = Convert.ToDouble(txtScore2.Text) // Not evaluated
decScore3 = Convert.ToDouble(txtScore3.Text) // Not evaluated
decScore4 = Convert.ToDouble(txtScore4.Text) // Not evaluated
decScore5 = Convert.ToDouble(txtScore5.Text) // Not evaluated
这些论文没有任何价值,作为回报,这不符合您的要求
decScoreAverage = (decScore1 + decScore2 + decScore3 + decScore4 + decScore5) / intDivideBy
<强>更新强> (Vb代码未经测试)
Function GetTextValue(dim score as string) as Double
dim value as Double = 0
if (Double.TryParse(score, value))
return value
else
return value
End Function
此
decScore1 = Convert.ToDouble(txtScore1.Text)
变为
decScore1 = GetTextValue(txtScore1.Text)
答案 1 :(得分:1)
我建议您存储对数组中每个文本框的引用。你会在这个例子的最后看到原因。
Public Class frmTestScoreAverage
Public Sub New()
Me.InitializeComponent()
Me.boxes = {Me.txtScore1, Me.txtScore2, Me.txtScore3, Me.txtScore4, Me.txtScore5}
End Sub
Private boxes As TextBox()
validate user input in winforms的常用方法是处理Validating事件,通常与error provider class提及的Hans Passant结合使用。
Private Sub HandleScoreValidating(sender As Object, e As System.ComponentModel.CancelEventArgs) Handles txtScore1.Validating, txtScore2.Validating, txtScore3.Validating, txtScore4.Validating, txtScore5.Validating
With DirectCast(sender, TextBox)
If ((Not String.IsNullOrEmpty(.Text)) AndAlso (Not Double.TryParse(.Text, 0.0R))) Then
e.Cancel = True
'Alert or set error provider:
'Me.ErrorProvider1.SetError(DirectCast(sender, Control), "Not double")
Else
e.Cancel = False
'Clear error provider:
'Me.ErrorProvider1.Clear()
End If
End With
End Sub
现在,回到文本框数组。创建一个新的double列表并迭代文本框数组。如果文本不为空,则解析并将值添加到列表中。最后,使用Average扩展方法获取平均值。
Private Sub HandleCalculate(sender As Object, e As EventArgs) Handles btnCalculate.Click
Dim values As New List(Of Double)
For Each box As TextBox In Me.boxes
If (Not String.IsNullOrEmpty(box.Text)) Then
values.Add(Double.Parse(box.Text))
'Else
' values.Add(0.0R)
End If
Next
Dim average As Double = values.Average()
'....
End Sub
End Class