簡體   English   中英

C#:在不選擇文本的情況下更改WinForm RichTextBox的字體樣式

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

我在我的代碼中使用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;

即使你看起來像漢斯的語法高亮文本框,它看起來並不像你正在使用它。

在突出顯示這些單詞時,您需要記住光標在進行突出顯示之前的位置和長度,因為在代碼中,您正在移動光標而不是將其放回原位。

如果沒有錯誤檢查,請嘗試將代碼更改為:

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

哎呀結果我錯誤地使用了Hans代碼。 我應該調用BeginUpdate()來停止繪制控件,並調用EndUpdate()來再次開始繪制它。 我反過來這樣做。

感謝所有的幫助,每個人(特別是漢斯)!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM