1

だから、私は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 がヒットするはずです。さらに重要なことに、文字を削除しても機能するはずです(バックスペースのキーを削除)。誰か?

編集:詳細:

リストボックスは、ユーザーが検索する内容に基づいて、キーストロークごとに縮小および拡大する必要があります。リストボックスは、ユーザーが入力したキーワードに一致するすべての項目を保持し、一致しない項目を除外する必要があります。

4

3 に答える 3

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);
}

免責事項:入力が正規表現パターンを「破壊」する場合があるかもしれません

于 2012-08-22T08:56:17.067 に答える
1

あなたのコードは l を頻繁に増加させます。例えば;

検索ワード「aaa bbb」を含むテキスト「aaa aaa aaa」は、「aaa」を見つけるたびに l を増やすため、l の 3 を返します。したがって、「bbb」が見つからなくても、これは一致します。

これを修正するには、keywordplit の見つかった部分を削除し、新しい選択行を検索するたびに、keywordplit を新たに再作成します。

l++;
break;

になる

l++
keywordSplit.RemoveAt[k];
break;

そして動く

string[] keywordSplit = keyword.Split(' ');

kループを開始する直前まで

少しクリーンで高速なコードを使用して、目的を達成するためのより良い方法があると思いますが、動作するはずです。

于 2012-08-22T07:50:35.790 に答える
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;
                        }
                    }
                }

今は問題なく動作しているようです。

于 2012-08-22T08:34:42.980 に答える