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
相关产品推荐
相关产品推荐

