A Textbox/Richtextbox That Has Syntax Highlighting? [C#]

A textbox/richtextbox that has syntax highlighting? [C#]

Scintilla.NET is probably what you're looking for

Syntax highlighting richtextbox in C# on a single line only

Well, you obviously need language lexer and parser. This task is not solvable by using Regex. It's just doesn't capable to accomplish this because of some fundamental grammar rules (or "power levels" of grammars) (read about Thomsky hierarchy of grammars).

What you need is to use some grammar toolkit. For example ANTLR4 provide grammar lexer/parser generator and set of already predefined grammars.

For example, you can find a lot of user-written grammars in here (including latest C# syntax): https://github.com/antlr/grammars-v4

Then just generate parser/lexer by it and feed it your string. It will output full hierarchy with indexes and lengths of each token, and you can colorize them without jumping across entire rich box.

Also, consider to use some timeout between user input, so you don't colorize your output every symbol (just save color from previous token, and use it for some time, until you recolorize output, then refresh). This way it will go as smoothly as it is in Visual Studio.

How to Syntax Highlight in a RichTextBox [C#]?

  • RichTextBox syntax highlighting (talks about RichTextBox itself - minimal features but exactly what you asked for here)
  • A textbox/richtextbox that has syntax highlighting? [C#] (talks mostly about other ways of doing it)

RichTextBox syntax highlighting

All I can suggest you right now is to use something stable, more powerful and less error prone such as Scintilla for .NET and Color Code. These controls are free and open source. Try them out:

ScintillaNET
ColorCode - Syntax Highlighting/Colorization for .NET

RichTextBox is extremely inefficient for working with large text. Even if you get some decent highlighting, the performance issues will start to pop up pretty soon.

How to implement basic syntax highlighting in Winforms RichTextBox?

Use the RichTextBox.Find(String, Int32, Int32, RichTextBoxFinds) method to find your strings in the control. You can then iterate by changing the Start point to the point after the current word.

Not sure on the performance of this scheme but it will work.

http://msdn.microsoft.com/en-us/library/yab8wkhy.aspx

add code syntax color winforms

I found FastColoredTextBox component which seems to be exactly what I need, answering in here in case someone else needs it.

Highlight bracketed parts of RichTextBox in C#

What you probably looking for is RichTextBox with syntax highlighting (what you try to highlight is similar to string highlighting in code editors).
There are many questions on stackoverflow with good answers already, e.g.
A textbox/richtextbox that has syntax highlighting? [C#]. If you must use RichTextBox you can start with the following code:

private void rtb_TextChanged(object sender, EventArgs e) {
var cursorPosition = rtb.SelectionStart;

rtb.SelectAll();
rtb.SelectionColor = Color.Black;

var partsToHighlight = Regex.Matches(rtb.Text, "{[^}{]*}")
.Cast<Match>()
.ToList();

foreach (var part in partsToHighlight) {
rtb.Select(part.Index, part.Length);
rtb.SelectionColor = Color.Red;
}

rtb.Select(cursorPosition, 0);
}

Unfortunately it causes flicker, loses scroll bar position and can take some time when processing huge blocks of text. Better approach is to use some custom control e.g. Scintilla:

public partial class Form1 : Form {
private readonly CustomLexer _lexer = new CustomLexer();

public Form1() {
InitializeComponent();

var editor = new ScintillaNET.Scintilla {
Dock = DockStyle.Fill,

};
this.Controls.Add(editor);

editor.StyleResetDefault();
editor.Styles[Style.Default].Font = "Consolas";
editor.Styles[Style.Default].Size = 10;
editor.StyleClearAll();

editor.Styles[CustomLexer.StyleText].ForeColor = Color.Black;
editor.Styles[CustomLexer.StyleParens].ForeColor = Color.Red;

editor.Lexer = Lexer.Container;
editor.StyleNeeded += scintilla_StyleNeeded;
}

private void scintilla_StyleNeeded(object sender, StyleNeededEventArgs e) {
var scintilla = (ScintillaNET.Scintilla)sender;

var startPos = scintilla.GetEndStyled();
var endPos = e.Position;

_lexer.Style(scintilla, startPos, endPos);
}
}

public class CustomLexer {
public const int StyleText = 0;
public const int StyleParens = 1;

private const int STATE_TEXT = 0;
private const int STATE_INSIDE_PARENS = 1;

public void Style(Scintilla scintilla, int startPosition, int endPosition) {
// Back up to the line start

var startLine = scintilla.LineFromPosition(startPosition);
var endLine = scintilla.LineFromPosition(endPosition);

var fixedStartPosition = scintilla.Lines[startLine].Position;
var fixedStopPosition = scintilla.Lines[endLine].Position + scintilla.Lines[endLine].Length;

scintilla.StartStyling(fixedStartPosition);

bool insideBrackets = false;
for (var i = fixedStartPosition; i < fixedStopPosition; i++) {
var c = (char)scintilla.GetCharAt(i);

if (c == '{') insideBrackets = true;

if (insideBrackets) {
scintilla.SetStyling(1, StyleParens);
}
else {
scintilla.SetStyling(1, StyleText);
}

if (c == '}') insideBrackets = false;
}
}
}

This is based on a great tutorial here.



Related Topics



Leave a reply



Submit