ComboBox显示新值但返回旧列表值的技术问题求助
解决ComboBox筛选后选择项返回原列表数据的问题
兄弟,折腾4小时确实闹心!我一眼就瞅出问题所在了——你绑定ComboBox的是筛选后的新列表,但填充DataGridView时,居然用SelectedIndex去原全局列表art里取数据!这俩列表的索引完全不对应啊,筛选后的列表第0项在原列表里可能是第N项,难怪拿到的是旧数据。
问题根源拆解
你筛选后把comboBox1.DataSource设为了新的filter列表,但填充代码里写的是:
row.Cells[0].Value = art[comboBox1.SelectedIndex].plu;
这里的art是原全局列表,而comboBox1.SelectedIndex是筛选后列表的索引,两者根本不匹配,自然拿错数据。
最优解决方案:直接用SelectedItem
既然ComboBox绑定的是artikal对象,那SelectedItem就是你选中的那个筛选后的对象,直接强转就能用,完全不用管索引,这也是最稳妥的方式:
修改你的DataGridView填充代码:
// 先判断是否选中了有效项,避免空引用异常 if (comboBox1.SelectedItem is artikal selectedArtikal) { row.Cells[0].Value = selectedArtikal.plu; row.Cells[1].Value = selectedArtikal.naziv; row.Cells[2].Value = selectedArtikal.kolicina; // 其他字段同理赋值 }
备选方案:保存筛选后的全局列表(不推荐,但适合特殊场景)
如果你非要用索引操作,可以把筛选后的列表存为全局变量,填充时用这个变量的索引:
- 先在窗体类里添加全局变量:
// 注意类型要和artikal一致,修正你代码里的List<item>为List<artikal> List<artikal> art = new List<artikal>(); List<artikal> currentFilteredArtikals = new List<artikal>();
- 修改TextChanged事件,把筛选后的列表赋值给全局变量:
private void textBox4_TextChanged_1(object sender, EventArgs e) { IEnumerable<artikal> filtered = from artikal in art where artikal.naziv.ToUpper().Contains(textBox4.Text.ToUpper()) || artikal.plu.Contains(textBox4.Text) || artikal.barkod.Contains(textBox4.Text) select artikal; comboBox1.DataSource = null; comboBox1.Items.Clear(); currentFilteredArtikals = filtered.ToList(); comboBox1.DataSource = currentFilteredArtikals; }
- 填充DataGridView时用这个全局筛选列表:
if (comboBox1.SelectedIndex != -1) { row.Cells[0].Value = currentFilteredArtikals[comboBox1.SelectedIndex].plu; row.Cells[1].Value = currentFilteredArtikals[comboBox1.SelectedIndex].naziv; }
额外小建议
- 遵循C#命名规范:类名和属性名用PascalCase,比如
artikal改成Artikal,plu改成Plu,这样代码可读性更高; - TextChanged事件里可以加个判断,如果输入为空,直接绑定原列表
art,提升用户体验:if (string.IsNullOrWhiteSpace(textBox4.Text)) { comboBox1.DataSource = art; return; } // 否则执行筛选逻辑
内容的提问来源于stack exchange,提问作者Stanislav Levčhenko
相关产品推荐
相关产品推荐

