簡體   English   中英

如何在 C# windows 表單 RichTextBox 中突出顯示 HTML 語法?

[英]How to highlight HTML syntax in C# windows form RichTextBox?

我正在編寫一個 c# Html 編輯器應用程序,您可以在其中的 RichTextBox 控件中鍵入代碼。 我希望 RichTextBox 的行為像 notepad++ 和其他代碼編輯器,其中 Html 語法在 colors 中突出顯示,例如:

例子

如何在 RichTextBox 的 C# windows 中建立這個? 我幾乎到處搜索,但沒有找到任何對我有幫助的東西。 這是我到目前為止嘗試過的,但我沒有給出我想要的結果:

private void SyntaxHighlight()
        {
            string[] tags = { "html","head","body","a","b","img","strong","p","h1","h2","h3","h4","h5","h6","embed","iframe","span","form",
                            "button","input","textarea","br","div","style","script","table","tr","td","th","i","u","link","meta","title"};
            foreach (string s in tags)
            {
                richTextBox1.Find("<" + s); 
                richTextBox1.SelectionColor = Color.Blue;
                richTextBox1.Find(">");
                richTextBox1.SelectionColor = Color.Blue;
            }

            string[] attributes = { "href","src","height","width","rowspan","colspan","target","style","onclick","id","name","class"};
            foreach (string s in attributes)
            {
                richTextBox1.Find(s + "=");
                richTextBox1.SelectionColor = Color.Red;
            }
        }

有人能幫我嗎? 我應該在 SyntaxHighlight() 方法中寫什么? 有人可以給我適當的代碼嗎? 謝謝

在您的代碼中,您只會發現HTML標記的第一個出現並將其突出顯示。 但是,您應該遍歷整個富文本內容,以查找同一文本的后續出現。 我只是根據您的確切代碼進行了快速模擬,請檢查一下。

    private void highlightHTMLText()
    {
        string[] tags = { "html","head","body","a","b","img","strong","p","h1","h2","h3","h4","h5","h6","embed","iframe","span","form",
                        "button","input","textarea","br","div","style","script","table","tr","td","th","i","u","link","meta","title"};
        foreach (string s in tags)
        {
            findAndHighlight("<" + s, Color.Blue);
            findAndHighlight("</" + s, Color.Blue);
            findAndHighlight(">", Color.Blue);
        }

        string[] attributes = { "href", "src", "height", "width", "rowspan", "colspan", "target", "style", "onclick", "id", "name", "class" };
        foreach (string s in attributes)
        {
            findAndHighlight(s + "=", Color.Red);
        }
    }

    private void findAndHighlight(string sSearchStr, Color oColor)
    {
        int index = richTextBox1.Text.IndexOf(sSearchStr);
        while (index != -1)
        {
            richTextBox1.Select(index, sSearchStr.Length);
            richTextBox1.SelectionColor = oColor;

            index = richTextBox1.Text.IndexOf(sSearchStr, index + sSearchStr.Length);
        }
    }

進一步根據答案,您應該能夠使用Notepad ++本身使用的相同實用程序庫Scintilla 如前所述,您不需要重新發明輪子,但是作為開發人員,我顯然更喜歡自己的util(就是我;))。 希望這可以幫助。

查找不會移動光標,它會返回第一個匹配項的位置。 嘗試以下方法:

如何從RichTextBox中選擇文本,然后為其着色?

晚會有點晚了,但在想創建自己的離線版本的 CodePen 之后,我按照 CodePen 的主題實現了自己的 html 語法高亮版本。

這會進行語法突出顯示和標記格式化,但格式化取決於您的 html 是否格式正確。

只需將其添加為您的 RichTextBox 的 class,相應地實例化它並在適合您的任何事件中調用它(我將它與 RTB 的 double_click 事件一起使用,但這確實消除了雙擊文本選擇)。 我打算做的是添加一個計時器,一些 boolean 變量,並在 key_up 和 key_down 事件中進行操作,以將突出顯示更新設置得更自動一些,對快捷方式的干擾更少。 (特此包含在類別下方)

    public void HighlightHTM(RichTextBox Htm_Input)
    {
        Htm_Input.Visible = false;
        #region store the original caret position + forecolor
        int originalIndex = Htm_Input.SelectionStart;
        int originalLength = Htm_Input.SelectionLength;
        Color originalColor = Color.FromArgb(200, 200, 200); // Grey
        #endregion
        #region try to format the markup
        try { Htm_Input.Text = XElement.Parse(Htm_Input.Text).ToString(); } catch { }
        #endregion
        #region match everything but puncutation and equals
        Regex e = new Regex(@"(.*?|=)[^\w\s]");
        MatchCollection eMatches = e.Matches(Htm_Input.Text);
        foreach (Match m in eMatches)
        {
            Htm_Input.SelectionStart = m.Groups[1].Index;
            Htm_Input.SelectionLength = m.Groups[1].Length;
            Htm_Input.SelectionColor = Color.FromArgb(221, 202, 126); // Yellow
        }
        #endregion
        #region match tags
        Regex t = new Regex(@"(<\w+|</\w+|/>|>)[^=]");
        MatchCollection tMatches = t.Matches(Htm_Input.Text, 0);
        foreach (Match m in tMatches)
        {
            Htm_Input.SelectionStart = m.Groups[1].Index;
            Htm_Input.SelectionLength = m.Groups[1].Length;
            Htm_Input.SelectionColor = Color.FromArgb(167, 146, 90); // Brown
        }
        #endregion
        #region match quotes
        Regex q = new Regex("\".*?\"");
        MatchCollection qMatches = q.Matches(Htm_Input.Text);
        foreach (Match m in qMatches)
        {
            Htm_Input.SelectionStart = m.Index;
            Htm_Input.SelectionLength = m.Length;
            Htm_Input.SelectionColor = Color.FromArgb(150, 179, 138); // Green
        }
        #endregion
        #region match inner html
        Regex h = new Regex(">(.+?)<");
        MatchCollection hMatches = h.Matches(Htm_Input.Text);
        foreach (Match m in hMatches)
        {
            Htm_Input.SelectionStart = m.Groups[1].Index;
            Htm_Input.SelectionLength = m.Groups[1].Length;
            Htm_Input.SelectionColor = Color.FromArgb(200, 200, 200); // Grey
        }
        #endregion
        #region restoring the original colors, for further writing
        Htm_Input.SelectionStart = originalIndex;
        Htm_Input.SelectionLength = originalLength;
        Htm_Input.SelectionColor = originalColor; // Light Grey
        #endregion
        Htm_Input.Focus();
        Htm_Input.Visible = true;
    }

編碼愉快!

編輯:我還應該提到 that.doctype 破壞了格式,因為它在“格式良好”的上下文中並不完全是 xml 友好的,為了我的目的,所有標簽包括正文和相關的關閉。 css 和 js 鏈接是在頁面保存時以編程方式添加的,因此在 html RTB 中僅使用正文標簽內的標記。 這消除了那個問題。

您會注意到這完全依賴於 Regex 而不是硬編碼的標簽和屬性。 我這樣做是因為標簽和屬性有一種經常在 w3 場景中出現和消失的趨勢。 這將迫使開發人員不斷地返回 go 並編輯這些字符串以刪除不推薦使用的標簽/屬性或添加新的。 不是最優的。

我還認為提前 go 並包括實例化/使用示例以使其更即插即用是明智的。

在 public Main() 之上,像這樣實例化:

    #region Class Instantiation
    SyntaxHighlight syntax = new SyntaxHighlight();
    #endregion

...並且,在您選擇的事件處理程序中,這樣稱呼它:

    private void htm_input_DoubleClick(object sender, EventArgs e)
    {
        syntax.HighlightHTM(Htm_Input);
    }

自然地,添加一個 SaveFileDialog 和一個 OpenFileDialog 幾乎可以提供您自己的功能,盡管非常基本,html 編輯器。 放入 WebBrowser 控件並將 RTB 的文本應用為 WebBrowser 的源,您就升級到了實時視圖。

至少,這應該作為一般語法突出顯示的可行參考。 它實際上歸結為識別模式並操縱它們的 colors,因此,例如,這將有效地與 css、javascript 甚至 C# 一起工作,只需對模式識別參數進行一些輕微調整。

以下是我如何使用 key_up / key_down 設置自動刷新並將計時器設置為 1000 毫秒:

    #region Globals
    int r = 0;
    bool refresh = false;
    #endregion
    private void Htm_Input_KeyUp(object sender, KeyEventArgs e)
    {
        refresh = true; // enter refresh cycle
    }
    private void Htm_Input_KeyDown(object sender, KeyEventArgs e)
    {
        refresh = false; // abort refresh cycle
    }
    private void Timer_Refresh_Tick(object sender, EventArgs e)
    {
        // check if refresh cycle is entered, refresh at 3 seconds or reset the counter if aborted
        if (refresh) { if (r == 3) { syntax.HighlightHTM(Htm_Input); refresh = false; r = 0; } r++; } else { r = 0; }
    }

暫無
暫無

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

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