WinForms中BindingSource设DataSource与ComboBox设DisplayMember顺序是否重要?
WinForms中BindingSource与ComboBox显示成员设置顺序的差异解析
问题现象
调换给BindingSource设置DataSource与给ComboBox设置DisplayMember的顺序,会出现两种截然不同的结果:
顺序1:先设置DisplayMember,再绑定BindingSource数据源
此时ComboBox无法显示Protocol实例的Name属性,反而输出类的全名myNameSpace.Protocol,两次MessageBox均显示空字符串:
Dictionary<string, BindingSource> bs = new Dictionary<string, BindingSource>() {"protocol", new BindingSource()}; this.protocolCombo.DataSource = bs["protocol"]; MessageBox.Show($"{this.protocolCombo.DisplayMember}"); //output: "" this.protocolCombo.DisplayMember = "Name"; MessageBox.Show($"{this.protocolCombo.DisplayMember}"); //output: "" bs["protocol"].DataSource = protocol_list;
顺序2:先绑定BindingSource数据源,再设置DisplayMember
ComboBox能正确显示Protocol实例的Name属性,第二次MessageBox输出"Name":
Dictionary<string, BindingSource> bs = new Dictionary<string, BindingSource>() {"protocol", new BindingSource()}; this.protocolCombo.DataSource = bs["protocol"]; MessageBox.Show($"{this.protocolCombo.DisplayMember}"); //output: "" bs["protocol"].DataSource = protocol_list; this.protocolCombo.DisplayMember = "Name"; MessageBox.Show($"{this.protocolCombo.DisplayMember}"); //output: "Name"
Protocol类简化定义:
public class Protocol { public string Name { get; set; } public Protocol(string name) { Name = name; } }
原因:这是WinForms的设计行为,而非缺陷
核心逻辑在于WinForms对DisplayMember的验证机制:
- 当ComboBox绑定的BindingSource为空时,设置
DisplayMember后,由于没有数据源可以验证属性是否存在,ComboBox内部会自动清除这个设置,所以两次MessageBox都输出空字符串。后续给BindingSource设置数据源时,ComboBox已丢失DisplayMember的配置,只能默认显示对象的ToString()结果(即类的全名)。 - 先给BindingSource设置数据源后,BindingSource已具备目标类型的元数据,此时设置
DisplayMember,ComboBox可以验证Name属性存在,成功保留配置,从而正确显示指定属性。
正确绑定顺序
为避免此类问题,建议遵循以下顺序:
- 初始化BindingSource并设置其
DataSource - 将BindingSource绑定到ComboBox
- 设置ComboBox的
DisplayMember(或ValueMember)
或者至少保证:在设置ComboBox的DisplayMember之前,先给BindingSource赋值有效的数据源。
内容的提问来源于stack exchange,提问作者alan6690
相关产品推荐
相关产品推荐

