C#: Changing font style of WinForm RichTextBox without selecting the text

别来无恙 提交于 2019-12-23 17:31:27

问题


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;

回答1:


Even though it looks like you incorporated Hans' syntax highlighting text box, it doesn't look like you are using it.

When highlighting those words, you need to remember the position and length of where your cursor is before you do the highlighting, because in your code, you are moving the cursor around and not putting it back.

Without error checking, try changing your code to this:

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



回答2:


Oops turns out I was using Hans code incorrectly. I was supposed to call BeginUpdate() to stop drawing control and EndUpdate() to start drawing it again. I was doing it the other way around.

Thanks for all the help, everyone (especially Hans)!



来源:https://stackoverflow.com/questions/12150634/c-changing-font-style-of-winform-richtextbox-without-selecting-the-text

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!