问题
I have a RichText, and want to implement a highlighting search, like you see in VS or Chrome. I got a fairly-working implementation going:
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
}
However, I want to support large amounts of text - up to 2MB. When there's a lot of text, each such update takes 250ms. That's OK for a single search - however, my search is incremental, which means that if the user type a 10-letter work, each letter appears after 250ms, which looks bad.
I implemented a wait using a timer:
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();
}
This works fairly well. However, it slows down the incremental search when the text is short, which is sub-optimal. I guess I could count the chars, but that feels like a hack...
Ideally, I'd like not to highlight when additional keystrokes are coming:
private void _txtSearch_TextChanged(object sender, EventArgs e)
{
if (!_txtSearch.Magic_are_additional_TextChanged_events_already_queued())
new RichTextNode(richTextBox1).Highlight(_txtSearch.Text);
}
Is there a way to do this? Or is the timer solution the best I can hope for?
回答1:
I ended up using the timer solution described in the question, with a delay of 1ms.
来源:https://stackoverflow.com/questions/15587767/implementing-searchhighlight-how-can-i-avoid-delays-when-highlight-is-slow