【问题标题】:DataGridView - Calculate and update a cell value based on other cellsDataGridView - 根据其他单元格计算和更新单元格值
【发布时间】:2019-04-23 14:43:28
【问题描述】:

我有 DataGridView,其数据源是一个 bindingList,我需要根据用户数据输入进行一些计算。

我希望能够允许用户在销售价值列 [列 7] 中输入一个值,然后将其与另一个单元格中的值一起使用(成本值 [列 8])来计算一个值对于行中的另一个单元格,边距值 [Col 9]。

i.e. 
Col 9 = col 7 - Col 8  (Margin = Sell Value -cost Value)

我在 DGV 的 CellValidating 事件中获得了此代码。 Case 参数是列索引。它有点罗嗦,因为我一直在使用调试语句来检查它的进展情况。

                Case 7
                Debug.Print("Checking Sell Value")
                If Not IsNumeric(dgvPurchaseOrderItems.Rows(e.RowIndex).Cells(e.ColumnIndex).EditedFormattedValue) Then
                    Debug.Print("Not a valid sell value")
                    dgvPurchaseOrderItems.Rows(e.RowIndex).ErrorText = "Need a valid sell value."
                    e.Cancel = True
                End If
                'update Margin Value
                Debug.Print("Sell Value OK - so updating Margin value")
                Debug.Print("Sell (edited Value): " & dgvPurchaseOrderItems.Rows(e.RowIndex).Cells(7).EditedFormattedValue)
                Debug.Print("Sell (Value): " & dgvPurchaseOrderItems.Rows(e.RowIndex).Cells(7).Value)

                SellValue = Convert.ToDecimal(dgvPurchaseOrderItems.Rows(e.RowIndex).Cells(7).EditedFormattedValue)
                Debug.Print("Sell Value (decimal): " & SellValue)
                costvalue = Convert.ToDecimal(dgvPurchaseOrderItems.Rows(e.RowIndex).Cells(8).Value)
                Debug.Print("Cost Value (decimal): " & costvalue)
                MarginValue = SellValue - costvalue
                Debug.Print("Margin Value:" & MarginValue)
                dgvPurchaseOrderItems.Rows(e.RowIndex).Cells(9).Value = MarginValue

            Case 8
                Debug.Print("Checking Cost Value ")
                If Not IsNumeric(dgvPurchaseOrderItems.Rows(e.RowIndex).Cells(e.ColumnIndex).EditedFormattedValue) Then
                    Debug.Print("Not a valid cost value")
                    dgvPurchaseOrderItems.Rows(e.RowIndex).ErrorText = "Need a valid cost value."
                    e.Cancel = True
                End If
                'update Margin Value
                Debug.Print("Cost Value OK - so updating Margin value")
                Debug.Print("Sell (edited Value): " & dgvPurchaseOrderItems.Rows(e.RowIndex).Cells(7).EditedFormattedValue)
                Debug.Print("Sell (Value): " & dgvPurchaseOrderItems.Rows(e.RowIndex).Cells(7).Value)
                Debug.Print("Cost (edited Value): " & dgvPurchaseOrderItems.Rows(e.RowIndex).Cells(8).EditedFormattedValue)
                Debug.Print("Cost (Value): " & dgvPurchaseOrderItems.Rows(e.RowIndex).Cells(8).Value)

                SellValue = Convert.ToDecimal(dgvPurchaseOrderItems.Rows(e.RowIndex).Cells(7).Value)
                Debug.Print("Sell Value (decimal): " & SellValue)
                costvalue = Convert.ToDecimal(dgvPurchaseOrderItems.Rows(e.RowIndex).Cells(8).EditedFormattedValue)
                Debug.Print("Cost Value (decimal): " & costvalue)
                MarginValue = SellValue - costvalue
                Debug.Print("Margin Value:" & MarginValue)
                dgvPurchaseOrderItems.Rows(e.RowIndex).Cells(9).Value = MarginValue

然而,虽然它似乎更新了 Cell 9,但 Col 7 的内容再次设置为 0。

我是否以正确的方式处理这件事?我应该使用 CellValidating 事件还是不同的东西?我不明白为什么当我不取消编辑时刚刚输入的单元格被重置为原始值?

啊,我在底层绑定列表的属性中进行了计算。这似乎行得通。

问题仍然存在 - 我应该更改 cellValidating 事件中的单元格的值、绑定列表属性还是其他地方?

谢谢

【问题讨论】:

  • 试图将 DGV 变成电子表格是个坏主意。大概Margin 是存储在BindingList 中的记录的一个属性。由于是计算值,所以应该是 ReadOnly 属性并返回计算值。
  • 您可以使用双向绑定来更新底层数据源,然后重新绑定stackoverflow.com/q/19467614/832052。您不应该使用 dgv 来存储状态 - 只显示它。
  • @TnTinMn - “试图将 DGV 变成电子表格是个坏主意。”我不是顺便说一句,但是是什么让你这么说? Noyes 在他的用 Windows 窗体进行数据绑定的书中说“用户想要类似电子表格的功能”。
  • @TnTinMn - 但是,我同意你的观点,Margin 是 bindingList 中的一个属性,并且是只读的。我获得了设置属性 sell 和 cost 来更新 Margin 属性的基础源变量,它似乎工作正常。干杯
  • @djv - 谢谢。关于存储 v 显示的好点。我不确定。

标签: vb.net


【解决方案1】:

答案是不要直接使用 CellValidating 事件中的计算来更新列。

相反,更改后端数据源中的值并依靠数据源和 DGV 之间的 2 路绑定将更改显示给用户。

所以我现在在 sell_value 属性中有这个,在 cost_value 属性中也有类似的。

当用户更改 DGV 中的销售或成本值时,将调用设置这些属性的绑定列表,然后运行计算以查找保证金成本,然后在只读模式中自动更新显示此属性的列。

Public Property sell_value() As Decimal
    Get
        Return _sell_value
    End Get
    Set(ByVal value As Decimal)
        _sell_value = value
        Debug.Print("Setting margin value in Sell_value Property")
        margin_value = _sell_value - _cost_value
        Debug.Print("Setting margin % in sell_value Property")
        If sell_value <> 0 Then
            margin_percent = _margin_value / sell_value
        Else
            margin_percent = 0
        End If
    End Set
End Property

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-26
    • 1970-01-01
    相关资源
    最近更新 更多