2

RichText があり、VS や Chrome で見られるように、ハイライト検索を実装したいと考えています。私はかなりうまくいく実装を手に入れました:

private void _txtSearch_TextChanged(object sender, EventArgs e)
{
    new RichTextNode(richTextBox1).Highlight(_txtSearch.Text);
}

public void Highlight(string text)
{
    textBox.BeginUpdate();   // Extension, implemented with P/Invoke

    textBox.SelectionStart = 0;
    textBox.SelectionLength = textBox.Text.Length;
    textBox.SelectionBackColor = textBox.BackColor;

    int highlights = 0;

    if (!string.IsNullOrEmpty(text))
    {
    int pos = 0;

    string boxText = textBox.Text;
    while ((pos = boxText.IndexOf(text, pos, StringComparison.OrdinalIgnoreCase)) != -1 && (highlights++) < 500)
    {
        textBox.SelectionStart = pos;
        textBox.SelectionLength = text.Length;

        textBox.SelectionBackColor = Color.Yellow;
        pos += text.Length;
    }
    }

    textBox.EndUpdate();  // Extension, implemented with P/Invoke
}

ただし、最大 2MB の大量のテキストをサポートしたいと考えています。テキストが多い場合、そのような更新ごとに 250 ミリ秒かかります。1 回の検索では問題ありませんが、私の検索はインクリメンタルです。つまり、ユーザーが 10 文字の作業を入力すると、各文字が 250 ミリ秒後に表示され、見栄えが悪くなります。

タイマーを使用して待機を実装しました。

private void _txtSearch_TextChanged(object sender, EventArgs e)
{
    performSearch.Stop();
    performSearch.Interval = 100; // Milliseconds
    performSearch.Start();
}

private void performSearch_Tick(object sender, EventArgs e)
{
    new RichTextNode(richTextBox1).Highlight(_txtSearch.Text);
    performSearch.Stop();
}

これはかなりうまく機能します。ただし、テキストが短い場合はインクリメンタル検索が遅くなり、最適ではありません。文字を数えることはできると思いますが、それはハックのように感じます...

理想的には、追加のキーストロークが発生したときに強調表示したくない:

private void _txtSearch_TextChanged(object sender, EventArgs e)
{
    if (!_txtSearch.Magic_are_additional_TextChanged_events_already_queued())
        new RichTextNode(richTextBox1).Highlight(_txtSearch.Text);
}

これを行う方法はありますか?または、タイマー ソリューションは私が期待できる最善の方法ですか?

4

1 に答える 1

0

質問で説明されているタイマーソリューションを1ミリ秒の遅延で使用することになりました。

于 2013-03-24T11:56:54.507 に答える