[英]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.