首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

C# RichTextBox 字型格式、顏色與語法高亮完整指南

     編輯:關於C#

一、字型格式與顏色基礎行為

RichTextBox 的 RTF 內容記錄位置屬性。設定第一個字元顏色後,Clear() 或 Text = "" 會清除樣式,重新設定文字時顏色恢復預設黑色。

richTextBox1.Text = "123";
richTextBox1.Select(0, 1);
richTextBox1.SelectionColor = Color.Red;
richTextBox1.Clear(); // 或 Text = ""
richTextBox1.Text = "abc"; // 顏色為黑色
richTextBox1.Text = "efg"; // 顏色為黑色

二、關鍵字語法高亮實作

public partial class RichTextBoxForm : Form
{
    public RichTextBoxForm()
    {
        InitializeComponent();
    }

    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 " };
        
        for (int i = 0; i < keystr.Length; i++)
            HighlightKeyword(keystr[i], this.tSql.Text);
        
        this.tSql.Select(index, 0); // 還原游標位置
        this.tSql.SelectionColor = Color.Black;
    }

    public int HighlightKeyword(string keyword, string text)
    {
        int cnt = 0;
        int M = keyword.Length;
        int N = text.Length;
        char[] ss = text.ToCharArray(), pp = keyword.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;
    }
}

三、高效能繪製建議(防止閃爍與游標跳動)

  1. 繼承 RichTextBox 並覆寫 OnPaint:自訂繪製邏輯,避免預設重繪問題。
  2. 暫停重繪:使用 WM_SETREDRAW 訊息鎖定更新:
[DllImport("user32.dll")]
private static extern int SendMessage(IntPtr hwnd, int wMsg, int wParam, IntPtr lParam);

private const int WM_SETREDRAW = 0x0B;

private void BeginPaint()
{
    SendMessage(richTextBox.Handle, WM_SETREDRAW, 0, IntPtr.Zero);
}

private void EndPaint()
{
    SendMessage(richTextBox.Handle, WM_SETREDRAW, 1, IntPtr.Zero);
    richTextBox.Refresh();
}

// 使用範例
private void HighlightAll()
{
    BeginPaint();
    try
    {
        // 大量 Select/SelectionColor 操作
    }
    finally
    {
        EndPaint();
    }
}

四、進階優化方向

  • 增量高亮:僅重新解析變更行/區塊,配合 TextChanged 事件的 e.Changes(需自行追蹤)。
  • 非同步解析:大文件時將解析移至背景執行緒,完成後回 UI 執行緒套用選取/顏色。
  • 使用 ScintillaNET:專業程式碼編輯元件,內建語法高亮、摺疊、自動完成,效能遠優於 RichTextBox。
  • RTF 直接操作:批次產生 RTF 字串一次指派 Rtf 屬性,避免大量 Select 呼叫。

五、常見陷阱

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
問題原因解決
高亮後游標跳到開頭SelectAll/Select 改變選取範圍記錄/還原 SelectionStart
輸入時畫面閃爍頻繁觸發重繪WM_SETREDRAW 暫停重繪
大文件卡頓O(n²) 字元比對 + 大量 Select增量解析、ScintillaNET、RTF 批次
中文關鍵字誤判逐字元比對不分詞使用 Regex \b 邊界或分詞器