【问题标题】:Revert the DataGridViewCell to the value before it was changed by the user将 DataGridViewCell 恢复为用户更改之前的值
【发布时间】:2017-03-24 20:46:22
【问题描述】:

我有一个这样的DataGridView

Quantidade 列可由用户更改,其他为只读。我想出了这段代码,如果用户在DataGridView 上手动更改Quantidade 的值,它会检查数据库以查看是否有足够的库存。因此,如果用户输入的值小于库存总值,它会正常更改,但我的问题是,如果用户输入的值大于库存值,我希望 DataGridViewCell 返回到更改之前的值由用户。

关于如何做到这一点的任何想法?

这是事件的代码:

Private Sub DataGridView1_CellValueChanged(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellValueChanged
   'this part is to check the total of the product in the db
    Dim Produtoid As String = DataGridView1.Rows(e.RowIndex).Cells(0).Value
    Dim tabelaqndDisponivel As DataTable = CAD.GetData("SELECT quantidadeExistenteProduto FROM Produto where idProduto = " & Produtoid)
    'qntDisponivel is a integer that holds the total quantity of the product in the db
    Dim qntDisponivel As Integer = tabelaqndDisponivel.Rows(0).Item(0)

    If DataGridView1.Rows(e.RowIndex).Cells(2).Value <= qntDisponivel Then
        'inserts normally
    Else
        'now here the value on cell "quantidade" should revert
    End If
End Sub

请注意,这个DataGridView 非常简单。它从ComboBox Produto 中获取值,并从TextBox Quantidade 中获取文本

【问题讨论】:

  • 好吧,我想我知道该怎么做了。因此,如果单元格验证保存“用户更改之前的值”,我可以将其保存在一个变量中,然后在 CellValueChanged 中,否则我可以将单元格值恢复为该变量

标签: vb.net datagridview


【解决方案1】:

我经常使用的另一种方法是将其保存到.Tag,每个对象都有一个.Tag,如果您想在整个代码中使用它,它会保存全局声明变量。

虽然不一定是更短的代码,但它有时确实非常有用,而且在我看来总体上更整洁,因为您不必声明变量(您可以将其保存到单元格或行 .Tag 但这更长代码)。

在您的应用程序中的用法:

Private Sub dataGridView1_CellValidating(ByVal sender As Object, ByVal e As DataGridViewCellValidatingEventArgs) Handles DataGridView1.CellValidating
    DataGridView1.Tag = DataGridView1.Rows(e.RowIndex).Cells(2).Value
End Sub

检索:

Else
    'now here the value on cell "quantidade" reverts to the value before being changed  
    DataGridView1.Rows(e.RowIndex).Cells(2).Value = DataGridView1.Tag
End If

【讨论】:

    【解决方案2】:

    我的回答是为您的代码的一些问题提供一些帮助。由于我们已经讨论了您手头的问题并且已经实施了修复,我认为解决这些问题是值得的。

    Option Strict On

    将隐式数据类型转换限制为仅扩展转换,禁止后期绑定,并禁止导致 Object 类型的隐式类型。

    第一个DataGridView1.Rows(e.RowIndex).Cells(0).ValueObject 类型,所以要解决这个问题,我们需要像这样附加.ToString()

    Dim Produtoid As String = DataGridView1.Rows(e.RowIndex).Cells(0).Value.ToString()
    

    第二个tabelaqndDisponivel.Rows(0).Item(0)DataGridView1.Rows(e.RowIndex).Cells(2).Value 也是Object。有了这些,我将使用Integer.TryParse 处理。然后,您还可以正确检查 Integer 值:

    Dim qntDisponivel As Integer = 0
    Dim qnt As Integer = 0 'You can give this a more meaningful name
    If Integer.TryParse(tabelaqndDisponivel.Rows(0).Item(0).ToString(), qntDisponivel) AndAlso
       Integer.TryParse(DataGridView1.Rows(e.RowIndex).Cells(2).Value.ToString(), qnt) Then
    
        If qnt <= qntDisponivel Then
            'inserts normally
        Else
            'now here the value on cell "quantidade" reverts to the value before being changed  
            DataGridView1.Rows(e.RowIndex).Cells(2).Value = valorqnt
        End If
    
    Else
        'Haven't been able to check so revert
        DataGridView1.Rows(e.RowIndex).Cells(2).Value = valorqnt
    
    End If
    

    第三个DataGridView1.Rows(e.RowIndex).Cells(2).Value 在你的CellValidating 方法中再次输入Object。改用Integer.TryParse:

    Integer.TryParse(DataGridView1.Rows(e.RowIndex).Cells(2).Value.ToString(), valorqnt)
    

    最后,您的 SQL 语句对 SQL 注入 开放。您需要查看 SQL 参数。在这方面很难提供太多帮助,因为我看不到 GetData 做了什么,这超出了这个问题的范围,但绝对值得一提。

    【讨论】:

      【解决方案3】:

      所以我在这里所做的是创建一个变量Private valorqnt As Integer 并在事件CellValidating 中将值(在用户更改之前)保存到其中。

      代码:

      Private Sub dataGridView1_CellValidating(ByVal sender As Object, ByVal e As DataGridViewCellValidatingEventArgs) Handles DataGridView1.CellValidating
          valorqnt = DataGridView1.Rows(e.RowIndex).Cells(2).Value
      End Sub
      

      这样我就可以在更改之前获得单元格的值。现在在CellValueChanged 事件中,我添加了DataGridView1.Rows(e.RowIndex).Cells(2).Value = valorqnt,这样我就可以恢复该值。

      代码:

      Private Sub DataGridView1_CellValueChanged(sender As Object, e As DataGridViewCellEventArgs) Handles DataGridView1.CellValueChanged
         'this part is to check the total of the product in the db
          Dim Produtoid As String = DataGridView1.Rows(e.RowIndex).Cells(0).Value
          Dim tabelaqndDisponivel As DataTable = CAD.GetData("SELECT quantidadeExistenteProduto FROM Produto where idProduto = " & Produtoid)
          'qntDisponivel is a integer that holds the total quantity of the product in the db
          Dim qntDisponivel As Integer = tabelaqndDisponivel.Rows(0).Item(0)
      
          If DataGridView1.Rows(e.RowIndex).Cells(2).Value <= qntDisponivel Then
              'inserts normally
          Else
              'now here the value on cell "quantidade" reverts to the value before being changed  
                  DataGridView1.Rows(e.RowIndex).Cells(2).Value = valorqnt
          End If
      End Sub
      

      【讨论】:

      • 很高兴您对它进行了排序。如另一个答案所示,使用Tag 可能是一个选项。我提供了一个关于尽量减少潜在运行时错误的答案。值得一看。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-05
      • 1970-01-01
      • 2021-11-01
      • 1970-01-01
      • 2018-03-12
      • 2016-08-01
      相关资源
      最近更新 更多