首页 > 解决方案 > 更正事件以计算 DataGridView 中的单元格值

问题描述

在 DataGridView 中,我使用此代码,CellEndEdit以自动计算金额乘以数量:

private void myGrid_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
    DataGridView oDGV = (DataGridView)sender; 
    DataGridViewCell oCell = oDGV.Rows[e.RowIndex].Cells[e.ColumnIndex];

    // Only the quantity can be changed
    if (oCell.Value != DBNull.Value && oCell.OwningColumn.Name == "num")
    {
        oDGV.EndEdit(); 
        int nNum = Convert.ToInt16(oCell.Value);
        decimal nPrice = Convert.ToDecimal(oDGV.Rows[e.RowIndex].Cells["price"].Value.ToString());
        decimal nTot = nPrice * nNum;
        oDGV.Rows[e.RowIndex].Cells["tot"].Value = nTot;
    }
}

显然是一个简单的操作,但它经常发生在我身上,计算没有执行,我必须回到单元格,再次输入值并按 Enter(即使屏幕上的一切都是正确的)。
我不明白问题出在哪里,也许我必须使用另一个事件?

标签: c#winformsdatagridview

解决方案


您有 3 列需要交互

  • price列:它应该指定一个Unit Price
  • numColumn:应该是Item的数量,Quantity
  • tot列:Total表示的值[Unit Price] * [Quantity]

由于第三列的 ( Total) 值是由价格 ( Unit Price) 乘以项目数 ( Quantity) 得到的,所以这个计算可以转移到DataTable.Expression:这个操作是固定的(它总是引用相同的列,它们总是具有相同的值类型)。

DataTable.Columns["Total"].Expression = "[Unit Price] * [Quantity]";

当然,在您的代码中,您使用分配给列的名称:

[Your DataTable].Columns["tot"].Expression = "[price] * [num]";

▶ 请注意,由于您要表示价格(货币),您可能希望使用 Decimal 类型来表示该 Value,而不是整数类型。这同样适用于Total列。

可以在加载 DataTable 或将其分配给DataGridView.DataSource属性之后立即分配表达式。
分配属性,引发DataSourceChanged事件:

private void myGrid_DataSourceChanged(object sender, EventArgs e)
{
    if (myGrid.DataSource is DataTable dt && dt.Columns.IndexOf("tot") >= 0) {
        dt.Columns["tot"].Expression = "[num] * [price]";
    }
}

▶ Cells 不需要包含值,[Unit Price][Quantity]can 都是null,不会抛出异常。您当然可以使用 DataGridViewNewRow向 DataTable 添加新行。

要在更改或值Total后立即更改 Column的值,请订阅或事件并验证编辑。在这种情况下,您无需按 Enter 或更改 Row 即可看到新的计算值出现,只需将光标移动到另一个相邻的单元格(Excel 样式)即可。Unit PriceQuantityCellEndEditCellValueChanged

private void myGrid_CellEndEdit(object sender, DataGridViewCellEventArgs e) => Validate();

推荐阅读