我需要一种动态的方法(在TextChanged事件上)突出显示RichTextBox的括号部分,但我被卡住了。 例如,如果文本是:
“这是{非常好}和{和平}早晨”
部分“{very nice}”和“{peacefull}”(包括括号)应该得到不同的文字颜色。
答案 0 :(得分:1)
您可能正在寻找的是具有语法突出显示功能的RichTextBox(您尝试突出显示的内容类似于代码编辑器中的字符串突出显示)。 stackoverflow上有很多问题已经有很好的答案,例如: A textbox/richtextbox that has syntax highlighting? [C#]。如果您必须使用RichTextBox,则可以使用以下代码启动:
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);
}
不幸的是,它会导致闪烁,丢失滚动条位置,并且在处理大量文本时可能需要一些时间。更好的方法是使用一些自定义控件,例如火花:
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;
}
}
}
这是基于一个很棒的教程here。