所以,我有一个包含x个项目的列表框。在列表框的顶部,我有一个TextBox(这是搜索字段)。我尝试开发一种算法,如果它不包含搜索词(代码中的变量关键字),则从列表框中删除项目。这应该发生在用户键入的每个键上(即时)。所以,代码:
private void _keywordTextBox_TextChanged(object sender, EventArgs e)
{
string keyword = _keywordTextBox.Text;
if (keyword == searchtext || isSpace) // do nothing if space is typed - searchtext is a templatetext in the textbox ("type here to search...")
return; // ignore
else if (keyword == "")
{
listBox.Items.Clear();
foreach (string s in originalList)
listBox.Items.Add(s);
}
else
{
List<string> selection = new List<string>();
foreach (string s in originalList) // originalList is the listbox at startup
selection.Add(s);
listBox.BeginUpdate();
string[] keywordSplit = keyword.Split(' ');
try
{
for (int i = originalList.Count - 1; i >= 0; i--)
{
string[] selectionSplit = selection[i].Split(' ');
int l = 0; // number of hits
for (int j = 0; j < selectionSplit.Length; j++)
{
for (int k = 0; k < keywordSplit.Length; k++)
{
if (selectionSplit[j].ToLower().Contains(keywordSplit[k].ToLower()))
{
l++;
break;
}
}
}
if (l < keywordSplit.Length) // Not hit on all keywords
selection.RemoveAt(i);
}
}
finally
{
listBox.Items.Clear();
foreach (string s in selection) // Add selection in listbox
listBox.Items.Add(s);
if (listBox.Items.Count > 0)
listBox.SetSelected(0, true); // Select first item in listbox
listBox.EndUpdate();
}
}
}
除了不能按预期工作之外,这个问题很难描述。据我所知,这种行为是零星的。
如果我搜索“ck flow”,我应该获得stackoverflow的命中。更重要的是,如果我删除字符(删除退格键)也应该有效。任何人
编辑:更多详情:
根据用户搜索的内容,列表框应在每次击键时缩小和增长。列表框应该保留与用户输入的关键字匹配的每个项目,并过滤掉不匹配的项目。
答案 0 :(得分:2)
或者您可以尝试制作正则表达式:
private void textBox1_TextChanged(object sender, EventArgs e)
{
string keyword = textBox1.Text;
if (string.IsNullOrEmpty(keyword.Trim()))
{
listBox1.Items.Clear();
listBox1.Items.AddRange(_originalList.ToArray());
}
else
{
Regex regex = new Regex(GetRegexPatternFromKeyword(keyword));
List<string> selection =
_originalList.Where(s => regex.IsMatch(s)).ToList();
listBox1.Items.Clear();
listBox1.Items.AddRange(selection.ToArray());
}
}
private static string GetRegexPatternFromKeyword(string keyword)
{
string[] words =
keyword.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).Select(word => "(?=.*" + word.Replace(")", @"\)") + ")").ToArray();
return string.Join("", words);
}
免责声明:在某些情况下,输入会“破坏”正则表达式模式
答案 1 :(得分:1)
您的代码经常增加l。例如;
带有搜索词'aaa bbb'的文字'aaa aaa aaa'将给出1的l,因为每次你找到'aaa'时你会增加l。所以这将是一场比赛,即使从未找到'bbb'。
您可以通过删除keywordsplit的已找到部分并在每次搜索新选择行之前重新创建keywordsplit来解决此问题(以及其他问题)。
l++;
break;
变为
l++
keywordSplit.RemoveAt[k];
break;
并移动
string[] keywordSplit = keyword.Split(' ');
到你开始k循环之前
Altough我觉得可能有更好的方法来实现你想要的东西,使用更干净,更快的代码。
答案 2 :(得分:0)
我得到了它的工作。 @IvoTops帮助我朝着正确的方向发展。只需首先循环所有关键字,然后选择选择。
for (int j = 0; j < keywordSplit.Length; j++)
{
for (int k = 0; k < selectionSplit.Length; k++)
{
if (selectionSplit[k].ToLower().Contains(keywordSplit[j].ToLower()))
{
l++;
break;
}
}
}
现在似乎正常工作。