C# WinForm二次打开XML文件时BindingSource数据绑定报错
问题根因
两个报错都是绑定逻辑的编写位置错误导致的:
- 你把
DataBindings.Add()、控件DataSource赋值的代码写在了打开文件的点击事件里,每次打开新文件都会重复执行一次。第一次打开时已经给对应控件的Text属性添加了绑定,第二次打开再执行Add方法,就会触发同一控件同一属性重复绑定的第一个异常。 - 你尝试在事件开头把
_bindingSource.DataSource = null,此时控件上已经存在的绑定会立刻去空数据源里查找NominalPower这类绑定字段,找不到就会抛出第二个“无法绑定到属性/列”的异常。 - 额外的无效逻辑:你给
dataGridView1添加Text属性绑定的代码完全没有作用,DataGridView靠DataSource绑定列表数据后会自动生成列,不需要单独给Text属性加绑定。
修复方案
核心原则:绑定关系只需要初始化一次,每次打开文件只更新数据源即可,不要重复创建绑定。
- 把所有绑定配置的代码从打开文件事件里挪出来,放到窗体构造函数(
InitializeComponent()调用之后)或者Form_Load事件里,整个程序生命周期只执行一次。 - 打开新文件时,先暂停绑定刷新,替换BindingSource的DataSource为新反序列化出来的列表,再恢复绑定即可,不需要重复添加绑定,也不需要提前把DataSource设为null。
- 删除
dataGridView1那行多余的Text绑定代码。
一次性绑定初始化代码示例
把这部分代码放到窗体构造函数或者Form_Load事件中,仅执行一次:
// 窗体构造函数示例 public MainForm() { InitializeComponent(); InitStaticBindings(); } private void InitStaticBindings() { // 配置机器名下拉框绑定,注意把DisplayMember替换成你MachineProfile类里实际存机器名的属性名 cmbMachineName.DisplayMember = "MachineName"; cmbMachineName.DataSource = _bindingSource; // 配置标签的字段绑定,仅执行一次 lblPower.DataBindings.Add("Text", _bindingSource, nameof(MachineProfile.NominalPower)); lblFrequency.DataBindings.Add("Text", _bindingSource, nameof(MachineProfile.Frequency)); lblMachineType.DataBindings.Add("Text", _bindingSource, nameof(MachineProfile.TypeDescription)); lblSpeed.DataBindings.Add("Text", _bindingSource, nameof(MachineProfile.NominalSpeed)); // 配置测量数据表格绑定 dataGridView1.AutoGenerateColumns = true; dataGridView1.DataSource = _bindingSource2; }
修复后的打开文件事件代码
private void openToolStripMenuItem_Click(object sender, EventArgs e) { using (OpenFileDialog ofd = new OpenFileDialog()) { ofd.Filter = "XML File (*.xml)|*.xml"; ofd.Title = "Open Client Profile File"; if (ofd.ShowDialog() == DialogResult.OK) { // 暂停绑定,避免数据源替换过程中触发无效刷新报错 _bindingSource.SuspendBinding(); _bindingSource2.SuspendBinding(); // 启用对应控件 lblCompanyName.Enabled = true; lblClientNumber.Enabled = true; lblSiteName.Enabled = true; lblMachineTotal.Enabled = true; lblImo.Enabled = true; cmbMachineName.Enabled = true; lblPower.Enabled = true; lblMachineType.Enabled = true; lblFrequency.Enabled = true; lblSpeed.Enabled = true; // 反序列化XML文件 _root = HelperXml.DeserializeXMLFileToObject<XmlRoot>(ofd.FileName); ClientFileName = ofd.FileName; // 赋值基础信息标签 lblCompanyName.ForeColor = Color.Black; lblCompanyName.Text = "Company Name: " + _root.CompanyProfile.CompanyName; lblSiteName.Text ="Sitename: " + _root.CompanyProfile.SiteName; lblImo.Text = "IMO: " + _root.CompanyProfile.Imo.ToString(); lblMachineTotal.Text = "Machine Total: " + _root.CompanyProfile.MachineTotal.ToString(); lblClientNumber.Text = "Clientnumber: " + _root.CompanyProfile.ClientNumber.ToString(); // 直接替换BindingSource的数据源即可,不需要重复添加绑定 _bindingSource.DataSource = _root.MachineProfiles.ToList(); _bindingSource2.DataSource = _root.MachineMeasurements.ToList(); // 恢复绑定,自动刷新所有控件显示 _bindingSource.ResumeBinding(); _bindingSource2.ResumeBinding(); } } string checkConnection = statusLblDevice.Text; // 同时加载文件且检测到设备时启用导入按钮 if (checkConnection.Contains("VM25") && !string.IsNullOrEmpty(lblSiteName.Text)) { importDataToolStripMenuItem.Enabled = true; } }
补充说明:如果后续需要做新建空白文件的功能,置空数据源前先调用
SuspendBinding(),清空操作完成后再调用ResumeBinding(),就不会出现找不到绑定字段的错误。
内容的提问来源于stack exchange,提问作者ElectricRay81
相关产品推荐
相关产品推荐

