C#开发中将DataGridView内容追加写入已有XML文件的问题排查
问题原因
你的代码出现这两个问题,是三个明确的逻辑错误导致的:
- 列名硬编码:创建DataTable列时固定使用
column+序号的命名规则,没有读取DataGridView列本身的HeaderText或Name属性,自然获取不到原有列名 - 写入逻辑冲突:先调用
DataSet.WriteXml()将表格数据写入文件,紧接着又调用仅存储了客户基础信息的XmlDocument对象的Save()方法,直接覆盖了刚写入的表格内容,最终文件自然只保留客户信息 - 冗余IO操作:新建XmlDocument后立刻保存再重新加载属于多余操作,内存中创建的XmlDocument对象可以直接编辑,不需要反复落盘读取
修复方案
1. 修复无法获取DataGridView原列名的问题
创建DataTable列时直接读取DataGridView列的属性,同时遍历行时跳过控件自动生成的空白新增行,避免写入无效空数据:
DataTable dt = new DataTable("Devices"); // 读取DataGridView原生列名创建DataTable列 for (int i = 0; i < dataGridView1.Columns.Count; i++) { string colName = dataGridView1.Columns[i].HeaderText; if (!string.IsNullOrWhiteSpace(colName)) { dt.Columns.Add(colName); } } // 遍历行时跳过空白新行 foreach (DataGridViewRow row in dataGridView1.Rows) { if (row.IsNewRow) continue; DataRow dr = dt.NewRow(); for (int j = 0; j < dataGridView1.Columns.Count; j++) { string colName = dataGridView1.Columns[j].HeaderText; if (!string.IsNullOrWhiteSpace(colName)) { dr[colName] = row.Cells[j].Value ?? DBNull.Value; } } dt.Rows.Add(dr); }
2. 修复数据无法追加写入XML的问题
不要混用XmlDocument和DataSet两套独立的XML写入逻辑,把所有需要存储的数据统一加载到DataSet中,所有内容组装完成后一次性写入文件,从根源避免覆盖问题。修正后的完整方法代码如下:
private void CreateClientFile() { string filename = $"{Company}_{SiteName}.xml"; string filePath = Path.Combine(@"C:\Users\NLRAGIL\Documents\10 - VibroManager\", filename); // 初始化DataSet,根节点命名为CompanyProfile DataSet ds = new DataSet("CompanyProfile"); // 组装客户基础信息表 DataTable profileTable = new DataTable("BasicInfo"); profileTable.Columns.Add("CompanyName", typeof(string)); profileTable.Columns.Add("Sitename", typeof(string)); profileTable.Columns.Add("IMO", typeof(string)); DataRow profileRow = profileTable.NewRow(); profileRow["CompanyName"] = CompanyName; profileRow["Sitename"] = SiteName; profileRow["IMO"] = IMO; profileTable.Rows.Add(profileRow); ds.Tables.Add(profileTable); // 组装DataGridView中的设备信息表 DataTable deviceTable = new DataTable("Devices"); for (int i = 0; i < dataGridView1.Columns.Count; i++) { string colName = dataGridView1.Columns[i].HeaderText; if (!string.IsNullOrWhiteSpace(colName)) { deviceTable.Columns.Add(colName); } } foreach (DataGridViewRow row in dataGridView1.Rows) { if (row.IsNewRow) continue; DataRow dr = deviceTable.NewRow(); for (int j = 0; j < dataGridView1.Columns.Count; j++) { string colName = dataGridView1.Columns[j].HeaderText; if (!string.IsNullOrWhiteSpace(colName)) { dr[colName] = row.Cells[j].Value ?? DBNull.Value; } } deviceTable.Rows.Add(dr); } ds.Tables.Add(deviceTable); // 所有数据组装完成后一次性写入XML,不存在覆盖问题 ds.WriteXml(filePath); // 调试输出 Console.WriteLine(ds.GetXml()); }
后续需要存储单台设备对应的测量数据时,只需要在DataSet中新增一张测量数据表,通过设备编号字段和
Devices表做关联,最后统一调用WriteXml方法即可将全部数据存入同一个XML文件,不需要反复读写文件。
内容的提问来源于stack exchange,提问作者ElectricRay81
相关产品推荐
相关产品推荐

