解決 RichTextBox 文字重置後顏色殘留、關鍵字即時著色、繪製效能優化三大核心問題。
現象:設定首字顏色後 Clear() 或 Text="",新文字仍保持舊顏色。
原因:RTF 內部記錄位置 0 的格式,重置文字從位置 0 開始寫入,繼承原格式。
解決:重置前先全選設定預設顏色:
richTextBox1.Text = "123";
richTextBox1.Select(0, 1);
richTextBox1.SelectionColor = Color.Red;
richTextBox1.SelectAll(); // 關鍵步驟
richTextBox1.SelectionColor = Color.Black; // 重置預設格式
richTextBox1.Clear(); // 或 Text = ""
richTextBox1.Text = "abc"; // 新文字為黑色
public partial class RichTextBox : Form {
private void tSql_TextChanged(object sender, EventArgs e) {
int index = this.tSql.SelectionStart; // 記錄游標位置
this.tSql.SelectAll();
this.tSql.SelectionColor = Color.Black; // 重置全黑
string[] keystr = { "select ", "from ", "where ", " and ", " or ", " order ", " by ",
" desc ", " when ", " case ", " then ", " end ", " on ", " in ", " is ", " else ",
" left ", " join ", " not ", " null " };
foreach (string kw in keystr) GetBunch(kw, this.tSql.Text);
this.tSql.Select(index, 0); // 還原游標
this.tSql.SelectionColor = Color.Black;
}
public int GetBunch(string p, string s) {
int cnt = 0;
int M = p.Length, N = s.Length;
char[] ss = s.ToCharArray(), pp = p.ToCharArray();
if (M > N) return 0;
for (int i = 0; i <= N - M; i++) {
int j;
for (j = 0; j < M; j++) if (ss[i + j] != pp[j]) break;
if (j == M) {
this.tSql.Select(i, M);
this.tSql.SelectionColor = Color.Blue;
cnt++;
}
}
return cnt;
}
}
效能提示:大文本頻繁 Select/Color 會造成閃爍,見下節優化。
繼承 RichTextBox 並重寫 Paint,配合 Win32 API 鎖定重繪:
[DllImport("user32")]
private static extern int SendMessage(IntPtr hwnd, int wMsg, int wParam, IntPtr lParam);
private const int WM_SETREDRAW = 0xB;
private void BeginPaint() {
SendMessage(yourRichTextBox.Handle, WM_SETREDRAW, 0, IntPtr.Zero); // 停止重繪
}
private void EndPaint() {
SendMessage(yourRichTextBox.Handle, WM_SETREDRAW, 1, IntPtr.Zero); // 恢復重繪
yourRichTextBox.Refresh(); // 強制單次重繪
}
著色邏輯包裹在 BeginPaint()/EndPaint() 之間,消除選取閃爍,大幅提升大文本著色流暢度。