You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WinForm DataGridView列值变更时如何实时自动计算行值

WinForm DataGridView 主从表自动计算列实现方案

不需要修改你现有的保存逻辑,按以下步骤实现即可覆盖「产品下拉选择变更、数量修改、新行录入」三个场景的实时自动计算:

  • 前提校验:确认绑定明细的DataGridView(对应tbl_intrari_detaliuBindingSource)中,id_produs的下拉列(DataGridViewComboBoxColumn)已正确绑定Products表,ValueMember设为id_produs,DisplayMember设为产品展示字段;同时明细数据源需包含pret_unitar(单价)、cantitate(数量)、valoare(金额)三个字段。

业务层面更推荐选产品时直接把对应单价存入明细行的pret_unitar字段,而非每次计算时实时从Products表读取,避免后续产品单价调整时,历史单据的金额被连带修改。

  • 第一步:注册两个DataGridView事件,解决下拉列选值后不即时触发变更的问题
    首先给控件绑定CurrentCellDirtyStateChanged事件,让下拉列选值后立刻提交编辑状态,不用等单元格失焦:
private void dgvDetalii_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
    if (dgvDetalii.IsCurrentCellDirty)
    {
        dgvDetalii.CommitEdit(DataGridViewDataErrorContexts.Commit);
    }
}
  • 第二步:编写核心计算逻辑,绑定CellValueChanged事件
    仅当cantitate、id_produs列值变化时触发计算,做好空值校验避免录入中途报错:
private void dgvDetalii_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
    // 跳过列头、未初始化的新行
    if (e.RowIndex < 0 || dgvDetalii.Rows[e.RowIndex].IsNewRow) return;

    DataGridViewRow currentRow = dgvDetalii.Rows[e.RowIndex];
    string changedColName = dgvDetalii.Columns[e.ColumnIndex].Name;

    // 仅监听数量、产品ID列的变更
    if (changedColName != "cantitate" && changedColName != "id_produs") return;

    object productIdVal = currentRow.Cells["id_produs"].Value;
    object cantitateVal = currentRow.Cells["cantitate"].Value;

    // 未完成录入时清空金额,避免计算错误
    if (productIdVal == null || cantitateVal == null)
    {
        currentRow.Cells["valoare"].Value = DBNull.Value;
        return;
    }

    // 取单价:如果单价存在明细行直接取,否则从Products表查询对应产品单价
    decimal pretUnitar;
    if (dgvDetalii.Columns.Contains("pret_unitar"))
    {
        pretUnitar = Convert.ToDecimal(currentRow.Cells["pret_unitar"].Value);
    }
    else
    {
        DataRow[] matchProduct = myDatabaseDataSet.Products.Select($"id_produs = {productIdVal}");
        if (matchProduct.Length == 0)
        {
            currentRow.Cells["valoare"].Value = DBNull.Value;
            return;
        }
        pretUnitar = Convert.ToDecimal(matchProduct[0]["pret_unitar"]);
    }

    decimal cantitate = Convert.ToDecimal(cantitateVal);
    // 赋值后自动同步到绑定源,不需要额外处理
    currentRow.Cells["valoare"].Value = pretUnitar * cantitate;
}
  • 补充配置:将valoare列的ReadOnly属性设为true,禁止用户手动修改计算结果,保证数据一致性。

你现有的保存按钮代码无需任何调整,计算出的valoare值会自动同步到绑定源,执行EndEdit和UpdateAll时会和其他字段一起提交到数据库。新行录入时只要选完产品、输入数量,就会自动触发计算逻辑,不需要单独给新行写事件。

内容的提问来源于stack exchange,提问作者Maria

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.01 23:06:28