C#中DataBindings绑定Dictionary报错:Cannot bind to the property or column
解决WinForms字典数据绑定抛出的"Cannot bind to the property or column..."异常
问题原因
WinForms的数据绑定机制不支持直接将Dictionary<string, double>作为数据源,并用字典的键作为dataMember参数传入DataBindings.Add方法——它会尝试在数据源对象上查找名为该键的属性/列,而字典本身并没有对应的属性,因此抛出异常。
解决方案
方案1:直接赋值(无需实时绑定)
如果只需要初始化时设置ValueLabel的文本,不需要后续字典值更新时自动同步,直接取值转换为字符串即可,这是最简单的解决方式:
public ZoneValue(Dictionary<string, double> voltages, string key) { InitializeComponent(); // 直接获取字典值并赋值 ValueLabel.Text = voltages[key].ToString(); KeyLabel.Text = key; ValueLabel.Left = (this.Width / 2) - (ValueLabel.Width / 2); KeyLabel.Left = (this.Width / 2) - (KeyLabel.Width / 2); }
方案2:实现实时数据绑定
如果需要字典值更新时,ValueLabel的文本自动同步,可以通过自定义包装类实现:
- 创建实现
INotifyPropertyChanged的包装类,封装字典访问:
public class VoltageWrapper : INotifyPropertyChanged { private readonly Dictionary<string, double> _voltages; public VoltageWrapper(Dictionary<string, double> voltages) { _voltages = voltages; } public double this[string key] { get => _voltages[key]; set { if (_voltages[key] != value) { _voltages[key] = value; OnPropertyChanged($"Item[{key}]"); } } } public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) { PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } }
- 在构造函数中使用包装类绑定:
public ZoneValue(Dictionary<string, double> voltages, string key) { InitializeComponent(); var voltageWrapper = new VoltageWrapper(voltages); // 绑定到包装类的索引器属性 ValueLabel.DataBindings.Add("Text", voltageWrapper, $"Item[{key}]"); KeyLabel.Text = key; ValueLabel.Left = (this.Width / 2) - (ValueLabel.Width / 2); KeyLabel.Left = (this.Width / 2) - (KeyLabel.Width / 2); }
后续通过voltageWrapper[key] = newValue更新字典值时,ValueLabel的文本会自动同步。
方案3:使用BindingSource(简化单向绑定)
如果不想自定义包装类,可借助BindingSource实现单向绑定(字典值更新不会自动同步Label,需手动触发刷新):
public ZoneValue(Dictionary<string, double> voltages, string key) { InitializeComponent(); var bindingSource = new BindingSource(); bindingSource.DataSource = voltages; // 绑定到字典的索引器 ValueLabel.DataBindings.Add("Text", bindingSource, $"[{key}]"); KeyLabel.Text = key; ValueLabel.Left = (this.Width / 2) - (ValueLabel.Width / 2); KeyLabel.Left = (this.Width / 2) - (KeyLabel.Width / 2); }
内容的提问来源于stack exchange,提问作者Trupti
相关产品推荐
相关产品推荐

