.NET控件ComboBox绑定数据源的一个Bug及解决方法

(原创文章,转载请注明来源:http://blog.csdn.net/hulihui)

 

ComboBox常用于绑定到一个数据源表的某个字段,提供选择并更新功能。下面用具体实例介绍它的一个Bug及解决办法。

1、演示Bug的代码

窗体Form1上有组合框comboBox1和一个显示数据表字段的按钮button1,演示代码如下:

private void Form1_Load(object sender, EventArgs e) { InitiateControl(); comboBox1.TabIndex = 0; } private void InitiateControl() { comboBox1.Items.Add("Red"); comboBox1.Items.Add("Blue"); comboBox1.Items.Add("Green"); comboBox1.DropDownStyle = ComboBoxStyle.DropDownList; DataTable colorTable = new DataTable(); colorTable.Columns.Add("Color", typeof(string)); colorTable.Rows.Add("Red"); comboBox1.DataBindings.Add("Text", colorTable, "Color"); } private void button1_Click(object sender, EventArgs e) { ShowColorValue(); comboBox1.Focus(); } private void ShowColorValue() { DataTable colorTable = comboBox1.DataBindings[0].DataSource as DataTable; DataRow row = colorTable.Rows[0]; MessageBox.Show(row["Color"].ToString()); }

InitiateControl()方法的功能:设定组合框comboBox1的DropDownStyle为DropDownList,填充其Items为3个颜色名;创建一个DataTable的数据表ColorTable,该表含字符型字段Color,并添加值为Red的行;最后绑定comboBox1的Text属性到ColorTable当前行的Color字段。

ShowColorValue()方法的功能:获取并显示组合框绑定数据源的第一行的Color字段值。

编译运行上述演示代码:

  • 击button1,显示的是初始值Red;
  • 如果用Mouse下拉组合框并选择任意一个颜色,然后点击button1,此时显示的也是comboBox1的Text值;
  • 如果在comboBox1控件上用光标键(左右上下翻页页首页尾键→、←、↑、↓、PageUp、PageDown、Home、End)选择一个颜色值,或用Mouse滚动选择一个颜色值,点击button1,此时显示的不是comboBox1的当前Text文本值,而是数据表ColorTable原来的值!就是说,选择的comBoxBox的Text值根本没有反映并回存数据表ColorTable中!

2、解决方法

查看comboBox1的DataBindings[0]属性(即Binding类对象),其WriteValue()用于写当前Text值到绑定数据源。只需要在SelectedIndex值改变时,调用该方法即可。为了利用下拉时组合框还是可以自动回写值到数据源的能力,可以设置一个标志boxDropDown,判断当前SelectedIndex是否由下拉动作激发。下面给出解决上述问题的代码。

public partial class Form1 : Form { bool boxDropDown = false; // 当前是否下拉组合框控件 int curSelectedIndex = -1; // 下拉组合框时的索引项值 public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { InitiateControl(); comboBox1.TabIndex = 0; BindingEvents(); // 绑定组合框两个事件 } private void InitiateControl() { comboBox1.Items.Add("Red"); comboBox1.Items.Add("Blue"); comboBox1.Items.Add("Green"); comboBox1.DropDownStyle = ComboBoxStyle.DropDownList; DataTable colorTable = new DataTable(); colorTable.Columns.Add("Color", typeof(string)); colorTable.Rows.Add("Red"); comboBox1.DataBindings.Add("Text", colorTable, "Color"); } private void BindingEvents() { this.comboBox1.DropDown += new System.EventHandler(this.comboBox1_DropDown); this.comboBox1.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged); } private void button1_Click(object sender, EventArgs e) { ShowColorValue(); comboBox1.Focus(); } private void ShowColorValue() { DataTable colorTable = comboBox1.DataBindings[0].DataSource as DataTable; DataRow row = colorTable.Rows[0]; MessageBox.Show(row["Color"].ToString()); } private void comboBox1_DropDown(object sender, EventArgs e) { curSelectedIndex = comboBox1.SelectedIndex; boxDropDown = true; } private void comboBox1_SelectedIndexChanged(object sender, EventArgs e) { if (curSelectedIndex != comboBox1.SelectedIndex && boxDropDown == false && comboBox1.DataBindings.Count > 0) { for (int k = 0; k < comboBox1.DataBindings.Count; k++) { comboBox1.DataBindings[k].WriteValue(); } } boxDropDown = false; } }

上述代码有如下改变:

  1. 增加了两个成员字段:boxDropDown、curSelectedIndex,第一用于表示是否下拉了组合框,第二个表示下拉时当前的选择项索引;
  2. 在Form1_Load方法中增加了一个绑定事件的方法BindingEvents(),该方法绑定组合框的DropDown事件和SelectedIndexChanged事件。第一个事件用于捕获是否有下拉动作,第二个事件用于捕获选择项值改变、没有下拉动作、有绑定数据源时回写选定值(即调用WriteValue()方法)。

3、结束语

使用VS2005+.NET 2.0、VS2008+.NET 3.5,Bug依然存在。特别指出,上述Bug仅在组合框DropDownStyle属性为DropDownList时存在。对DropDrowDtyle为DropDown时,不管是鼠标下拉还是键盘选择,ComboBox控件均自动回写当前Text值到绑定的数据源中。

你可能感兴趣的:(.net,object,String,dropdown,button,binding)