I am using a RichTextBox
in my code where I show syntax-highlighted code. Now, on every keystroke, I have to re-parse all the tokens and re-color them all over again. But the only way to color individual words in a WinForm richtextbox
is to select those words one by one and color them using SelectionFont.
But if the user is typing really fast, there is a very noticeable flickering caused by my selecting individual words (selected words have that Windows blue-background thing and that is causing the flickering). Is there any way around that where I can color individual words without selecting them (and hence causing that blue highlight around the selected text). I tried using SuspendLayout()
to disable rendering during my coloring but that didn't help. Thanks in advance!
Here is my code:
Code:
private void editBox_TextChanged(object sender, EventArgs e) {
syntaxHighlightFromRegex();
}
private void syntaxHighlightFromRegex() {
this.editBox.SuspendLayout();
string REG_EX_KEYWORDS = @"\bSELECT\b|\bFROM\b|\bWHERE\b|\bCONTAINS\b|\bIN\b|\bIS\b|\bLIKE\b|\bNONE\b|\bNOT\b|\bNULL\b|\bOR\b";
matchRExpression(this.editBox, REG_EX_KEYWORDS, KeywordsSyntaxHighlightFont, KeywordSyntaxHighlightFontColor);
}
private void matchRExpression(RichTextBox textBox, string regexpression, Font font, Color color) {
System.Text.RegularExpressions.MatchCollection matches = Regex.Matches(this.editBox.Text, regexpression, RegexOptions.IgnoreCase);
foreach (Match match in matches) {
textBox.Select(match.Index, match.Length);
textBox.SelectionColor = color;
textBox.SelectionFont = font;
}
}
Inside the MyRichTextBox (dervied from RichTextBox):
public void BeginUpdate() {
SendMessage(this.Handle, WM_SETREDRAW, (IntPtr)0, IntPtr.Zero);
}
public void EndUpdate() {
SendMessage(this.Handle, WM_SETREDRAW, (IntPtr)1, IntPtr.Zero);
}
[DllImport("user32.dll")]
private static extern IntPtr SendMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);
private const int WM_SETREDRAW = 0x0b;