C# combobox的过滤-奇怪的行为
我的WinForms应用程序中有一个组合框,您可以在其中搜索字符串并相应地过滤结果,但它的行为似乎非常奇怪。我正在搜索“Coo”,我得到了一个很长的产品列表,其中不包含字符串“Coo”()。然而,当我输入“coor”然后按backspace,让我再次输入“coo”时,结果列表是不同的() 我正在使用“KeyPress”事件处理程序在组合框中搜索。代码如下所示C# combobox的过滤-奇怪的行为,c#,winforms,C#,Winforms,我的WinForms应用程序中有一个组合框,您可以在其中搜索字符串并相应地过滤结果,但它的行为似乎非常奇怪。我正在搜索“Coo”,我得到了一个很长的产品列表,其中不包含字符串“Coo”()。然而,当我输入“coor”然后按backspace,让我再次输入“coo”时,结果列表是不同的() 我正在使用“KeyPress”事件处理程序在组合框中搜索。代码如下所示 private void comboBox1_KeyPress(object sender, KeyPressEventArgs e)
private void comboBox1_KeyPress(object sender, KeyPressEventArgs e)
{
comboBox1.Items.Clear();
listNew.Clear();
var source = new AutoCompleteStringCollection();
foreach (var item in listOnit)
{
if (item.ToLower().Contains(this.comboBox1.Text.ToLower()))
{
listNew.Add(item);
}
}
comboBox1.Items.AddRange(listNew.ToArray());
comboBox1.SelectionStart = this.comboBox1.Text.Length;
Cursor = Cursors.Default;
comboBox1.DroppedDown = true;
}
我做错什么了吗?该列表是从数据库填充的
string sqlProducts = "SELECT Description FROM stocktake_products WHERE stocktake_id = '" + stocktakeID.stocktake_id + "' AND (PLUProdCode IS NULL OR PLUProdCode = '');";
MySqlCommand cmdProduct = new MySqlCommand(sqlProducts, conn);
cmdProduct.CommandTimeout = 10000;
MySqlDataReader rdrProduct = cmdProduct.ExecuteReader();
AutoCompleteStringCollection myCollectionSales1 = new AutoCompleteStringCollection();
if (rdrProduct.HasRows == true)
{
while (rdrProduct.Read())
{
// myCollectionSales1.Add(rdrProduct[0].ToString());
listOnit.Add(rdrProduct[0].ToString());
}
rdrProduct.Close();
//textBox1.AutoCompleteCustomSource = myCollectionSales1;
comboBox1.Items.AddRange(listOnit.ToArray());
}
我希望组合框只显示包含已键入的整个字符串的结果,而不是在任何位置键入字母的每个短语,因为它似乎就是这样做的
我尝试过使用BeginIvoke方法(不确定是否正确,因为我以前从未使用过它)
现在,当我开始键入第一个字符时,组合框会立即选择顶部结果()。我必须再次按第一个字符,然后键入字符串的其余部分,才能真正在列表中搜索。这只是对KeyPress工作原理的一个简单误解。它在添加角色之前触发,因此当您键入“coo”时,您将搜索“co”。通过使用this.BeginInvoke()优雅地修复了此问题,因此代码在击键处理后运行。何时添加this.BeginInvocek()?在处理程序定义之后?在按键事件处理程序中。我已经用稍微不同的代码完成了。我使用了您提供的示例,结果仍然相同。当我开始键入第一个字符时,组合框会立即选择顶部结果()。我必须再次按第一个字符,然后键入字符串的其余部分,以便能够实际搜索列表。每次击键时,都会从数据库填充列表。但如果用户输入“coor”,他们对“c”、“co”和“coo”的三个过滤器不感兴趣。我建议您只在一个小的不活动延迟后,也许一秒钟,才开始过滤。如果用户输入足够快,他们将有更好的体验。另外,如果用户按下一个新键,您可以停止当前的DB活动,这也很好。
this.BeginInvoke((MethodInvoker)delegate
{
comboBox1.Items.Clear();
listNew.Clear();
var source = new AutoCompleteStringCollection();
foreach (var item in listOnit)
{
if (item.ToLower().Contains(this.comboBox1.Text.ToLower()))
{
listNew.Add(item);
}
}
comboBox1.Items.AddRange(listNew.ToArray());
comboBox1.SelectionStart = this.comboBox1.Text.Length;
Cursor = Cursors.Default;
comboBox1.DroppedDown = true;
});