WinForm数据绑定必须通过BindingSource中间层,它提供事件通知、排序筛选等功能;绑定需设DataSource和DataMember;双向同步依赖INotifyPropertyChanged接口实现;ComboBox需显式设置DisplayMember/ValueMember;Current属性用于获取当前选中项。
WinForm 的数据绑定不是“设个属性就自动同步”,它依赖 BindingSource 中间层和控件的 DataSource / DataMember 配合,直接绑 List
BindingSource 不只是“包装器”,它提供事件通知、排序、筛选、当前项管理等能力。没有它,很多控件(如 DataGridView、ComboBox)无法响应数据变化或无法正确显示编辑状态。
List、DataTable)赋给 BindingSource.DataSource
Orders[0].ProductName),需用 DataMember 指定路径,否则默认只读第一层DataMember 填字段名(如 "Name");绑定到 DataGridView 时通常留空,由列的 DataPropertyName 分别指定var bs = new BindingSource(); bs.DataSource = new List{ new Person { Name = "张三", Age = 28 } }; textBox1.DataBindings.Add("Text", bs, "Name"); // 此处 "Name" 是 Person 的属性名 dataGridView1.DataSource = bs; // 自动映射所有 public 属性
BindingSource

ResetBindings()。要让 TextBox 编辑后自动更新对象、对象属性变化后自动刷新 UI,必须让数据类实现 INotifyPropertyChanged。
public class Person : INotifyPropertyChanged
{
private string _name;
public string Name
{
get => _name;
set { _name = value; OnPropertyChanged(); }
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
直接绑 ListToString() 结果(通常是类型名),这不是 bug,是默认行为。必须显式设置 DisplayMember 和 ValueMember 才能按需展示和取值。
DisplayMember:决定下拉列表中显示哪一列(对应对象属性名)ValueMember:决定 SelectedValue 返回什么(常用于主键 ID)DisplayMember 没设 ValueMember,SelectedValue 将返回整个对象,容易引发类型转换错误comboBox1.DataSource = bs; comboBox1.DisplayMember = "Name"; // 显示姓名 comboBox1.ValueMember = "Id"; // 取值时返回 Id 字段
BindingSource 的 Current 属性常被忽略——它才是当前选中行的实时引用。很多逻辑(比如点击按钮保存当前编辑行)应该从 bs.Current as Person 获取,而不是从原始 List 里按索引硬取,否则可能和 UI 当前状态不一致。