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

C# Winforms中DataGridView价格变动时批量更新关联网格匹配值方案咨询

最优实现方案:DataTable 关联表达式列(无需手动遍历)

核心原理:.NET 的 DataTable 原生支持计算列(Expression 属性)和表间关联(DataRelation),可以直接实现类似 Excel 单元格引用的自动同步效果,所有同步逻辑由 ADO.NET 框架底层处理,性能远高于手动遍历行。


具体实现步骤

步骤1:定义数据源结构并绑定到DataGridView

// 全局声明数据源
DataSet ds = new DataSet();
DataTable dtMaster; // 主商品表
DataTable dtDetail; // 从销售记录表

private void Form1_Load(object sender, EventArgs e)
{
    // 1. 初始化主商品表
    dtMaster = new DataTable("MasterItems");
    dtMaster.Columns.Add("ITEMNAME", typeof(string));
    dtMaster.Columns.Add("PRICE", typeof(decimal));
    // 填充示例主表数据
    dtMaster.Rows.Add("MOUSE", 399.00m);
    dtMaster.Rows.Add("PRINTER", 12000.00m);
    dtMaster.Rows.Add("MONITOR", 18500.00m);
    // 设置商品名为主键,避免重复商品
    dtMaster.PrimaryKey = new DataColumn[] { dtMaster.Columns["ITEMNAME"] };
    ds.Tables.Add(dtMaster);
    // 绑定主网格
    dgvMaster.DataSource = dtMaster;

    // 2. 初始化从销售记录表
    dtDetail = new DataTable("SaleRecords");
    dtDetail.Columns.Add("CUSTOMERNAME", typeof(string));
    dtDetail.Columns.Add("ITEMNAME", typeof(string));
    dtDetail.Columns.Add("PRICE", typeof(decimal));
    // 填充示例从表数据(仅需填客户名和商品名,价格自动关联)
    dtDetail.Rows.Add("ANANT H", "MOUSE");
    dtDetail.Rows.Add("JOLLY K", "MONITOR");
    dtDetail.Rows.Add("ANANT H", "MOUSE");
    dtDetail.Rows.Add("KIRAN A", "PRINTER");
    dtDetail.Rows.Add("KIRAN A", "MOUSE");
    ds.Tables.Add(dtDetail);
}

步骤2:建立主从关联,设置从表价格为自动引用列

// 继续放在Form1_Load方法末尾执行
// 建立主从表关联,关联字段为商品名ITEMNAME
DataRelation priceRelation = new DataRelation(
    "ItemPriceRef",
    dtMaster.Columns["ITEMNAME"],
    dtDetail.Columns["ITEMNAME"]
);
ds.Relations.Add(priceRelation);

// 给从表的PRICE列设置关联表达式,自动引用主表的对应价格
dtDetail.Columns["PRICE"].Expression = "Parent(ItemPriceRef).PRICE";

// 绑定从网格
dgvDetail.DataSource = dtDetail;

效果说明

无需编写任何监听主表修改的额外代码,只要主表中任意商品的PRICE值发生变更,从表所有对应商品的PRICE列会自动同步更新,完全匹配你需要的Excel单元格引用效果。底层由ADO.NET直接处理,即使从表有十万级以上数据,同步速度也远快于手动循环遍历匹配。


次优方案(特殊场景无法使用表达式列时选择)

如果业务场景不允许使用计算列,可以用DataView.RowFilter过滤匹配行,避免全表遍历:

// 主网格编辑完成事件
private void dgvMaster_CellEndEdit(object sender, DataGridViewCellEventArgs e)
{
    // 判断是否修改的是价格列
    if (e.ColumnIndex == dtMaster.Columns["PRICE"].Ordinal)
    {
        string modifiedItem = dtMaster.Rows[e.RowIndex]["ITEMNAME"].ToString();
        decimal newPrice = (decimal)dtMaster.Rows[e.RowIndex]["PRICE"];
        
        // 过滤出所有对应商品的行,仅遍历匹配结果
        dtDetail.DefaultView.RowFilter = $"ITEMNAME = '{modifiedItem.Replace("'", "''")}'";
        foreach (DataRowView row in dtDetail.DefaultView)
        {
            row["PRICE"] = newPrice;
        }
        dtDetail.DefaultView.RowFilter = "";
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 14:27:08