我在我的代码中使用RichTextBox
,其中显示了突出显示语法的代码。现在,在每次按键时,我必须重新解析所有令牌并重新对它们进行重新着色。但是,在WinForm richtextbox
中为单个单词着色的唯一方法是逐个选择这些单词并使用SelectionFont为它们着色。
但是如果用户输入的速度非常快,那么我选择单个单词会导致非常明显的闪烁(所选单词具有Windows蓝色背景,导致闪烁)。有什么方法我可以在不选择它们的情况下为单个单词着色(从而在所选文本周围产生蓝色高光)。我尝试使用SuspendLayout()
在着色期间禁用渲染,但这没有帮助。提前谢谢!
这是我的代码:
代码:
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;
}
}
MyRichTextBox内部(从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;
答案 0 :(得分:1)
即使您看起来像是汉语的语法高亮文本框,但它看起来并不像您正在使用它。
在突出显示这些单词时,您需要记住光标在进行突出显示之前的位置和长度,因为在您的代码中,您正在移动光标而不是将其放回去。
如果没有错误检查,请尝试将代码更改为:
void editBox_TextChanged(object sender, EventArgs e) {
this.editBox.BeginUpdate();
int lastIndex = editBox.SelectionStart;
int lastLength = editBox.SelectionLength;
syntaxHighlightFromRegex();
editBox.Select(lastIndex, lastLength);
this.editBox.SelectionColor = Color.Black;
this.editBox.EndUpdate();
this.editBox.Invalidate();
}
答案 1 :(得分:0)
哎呀说我错误地使用了Hans代码。我应该调用BeginUpdate()来停止绘制控件,并调用EndUpdate()来再次开始绘制它。我反过来这样做。
感谢所有人的帮助,每个人(尤其是汉斯)!