你的第一个问题是你想把苹果和橙子加在一起。
行内:
totalSum += dataGridView1.Rows(i).Cells(5).Value
totalSum 是一个整数,而 DataGridView 单元格的 Value 属性是 object 类型。
这与您在尝试使用 DataTable 时看到的问题相似,只是您的 Item 属性给您一个 DBNull 而不是返回一个对象。
这是您想要的代码(我主要是 C# 开发人员,因此 VB.Net 可能缺乏优雅,但它可以工作)。
Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
Dim sum As Integer
sum = 0
For Each row As DataGridViewRow In DataGridView1.Rows
Dim current As Integer
If Integer.TryParse(row.Cells("OrderQty").Value.ToString, current) Then
sum += current
End If
Next
TextBox1.Text = sum.ToString
End Sub
关于该代码的一些值得注意的事情:
- 我使用 For Each 而不是 for。两者的表现基本相同,但我发现 foreach 更具可读性
- 我在使用之前对单元格值使用 Integer.TryParse。这比直接转换单元格值更安全。
- 我使用列名,而不是使用有点脆弱的列索引。
通过检查复选框是否被选中,您可以执行类似的操作:
Boolean.TryParse(row.Cells("IsChecked").Value.ToString, cb)
最后要注意的一点是,如果您尝试在 DataGridView 的 cellclick 方法中执行此代码,您将遇到问题 - 复选框状态直到 cellclick 之后才提交,因此最近检查的单元格不会得到添加到您的计数中。相反,您需要处理 CellDirtyStateChanged 并提交编辑,然后在 CellValueChanged 处理程序中求和。
为了说明,试试这个代码:
Private Sub dgv_CellContentClick(ByVal sender As Object, ByVal e As DataGridViewCellEventArgs) Handles DataGridView1.CellClick
Dim sum As Integer
sum = 0
Dim cb As Boolean
cb = False
If DataGridView1.Columns(e.ColumnIndex).Name <> "IsChecked" Then
Return
End If
For Each row As DataGridViewRow In DataGridView1.Rows
If Boolean.TryParse(row.Cells("IsChecked").Value.ToString, cb) Then
If cb Then
Dim current As Integer
If Integer.TryParse(row.Cells("OrderQty").Value.ToString, current) Then
sum += current
End If
End If
End If
Next
TextBox1.Text = sum.ToString
End Sub
总和总是会滞后单击一次(实际上在 VB.Net 中它似乎并没有真正起作用 - 但我更像是一个 c# 开发人员,所以我可能会遗漏一些东西)。
相反,你想要:
Sub dataGridView1_CurrentCellDirtyStateChanged( _
ByVal sender As Object, ByVal e As EventArgs) _
Handles DataGridView1.CurrentCellDirtyStateChanged
If DataGridView1.IsCurrentCellDirty Then
DataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit)
End If
End Sub
' If a check box cell is clicked, this event handler disables
' or enables the button in the same row as the clicked cell.
Public Sub dataGridView1_CellValueChanged(ByVal sender As Object, _
ByVal e As DataGridViewCellEventArgs) _
Handles DataGridView1.CellValueChanged
If DataGridView1.Columns(e.ColumnIndex).Name = "IsChecked" Then
Dim sum As Integer
sum = 0
Dim cb As Boolean
For Each row As DataGridViewRow In DataGridView1.Rows
If Boolean.TryParse(row.Cells("IsChecked").Value.ToString, cb) Then
If cb Then
Dim current As Integer
If Integer.TryParse(row.Cells("OrderQty").Value.ToString, current) Then
sum += current
End If
End If
End If
Next
TextBox1.Text = sum.ToString
End If
End Sub