[英]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(就是我;))。 希望這可以幫助。
查找不會移動光標,它會返回第一個匹配項的位置。 嘗試以下方法:
晚會有點晚了,但在想創建自己的離線版本的 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.