RichTextBox - 如何突出显示行尾?
RichTextBox - How highlight end of line?
如果搜索到的词在的行首或行尾,我想给它上色。如果它在线的中间则不是彩色的。我尝试了很多东西,但效果不佳。
似乎该行的开头正在运行。但是第一行的结尾只能着色。我想为所有行结束着色。我想我需要每一行开始和循环的索引,但我做不到。
我该如何解决?
private void button1_Click(object sender, EventArgs e)
{
int wordLength = textBox1.Text.Length;
string word = textBox1.Text;
for (int i = 0; i < richTextBox1.Lines.Count(); i++)
{
int startIndex = richTextBox1.GetFirstCharIndexFromLine(i);
richTextBox1.Find(word, startIndex, startIndex+wordLength, RichTextBoxFinds.None);
richTextBox1.SelectionColor = Color.Red;
richTextBox1.SelectionBackColor = Color.Yellow;
int newLineIndex = richTextBox1.Lines[i].Length;
richTextBox1.Find(textBox1.Text, (newLineIndex - wordLength), newLineIndex, RichTextBoxFinds.None);
richTextBox1.SelectionColor = Color.Red;
richTextBox1.SelectionBackColor = Color.Yellow;
}
尝试:
int newLineIndex = i + 1 < richTextBox1.Lines.Length ? richTextBox1.GetFirstCharIndexFromLine(i + 1) - 1 : richTextBox1.TextLength;
我建议稍微更改一下您的代码。当 RichTextBox 文本长度增长时,您会注意到原因。
询问 Lines[]
内容并不是一件好事,在循环中更糟糕,当您可能多次访问此 属性 时。
您可以在 .Net Source Code 中看到发生了什么(每次 - Lines
属性 值未被缓存且不能被缓存)。
GetLineFromCharIndex()
和 GetFirstCharIndexFromLine()
使用 SendMessage
将 EM_LINEFROMCHAR
和 EM_LINEINDEX
消息发送到使用缓存值的编辑控件,并且是相当快。
- 使用
Regex.Matches()
收集匹配词的索引(可以使用多个词,用竖线分隔:"|"
,但这里我们只处理一个词。当匹配多个单词时,使用 List<Match>
和 Match.Length
而不是 searchWord.Length
) 并仅提取每个匹配项的索引位置。
- 然后循环索引,检查当前索引位置是否满足条件。
- 以
IndexOf("\n", [StartPosition])
找到当前行结尾,使用第一行索引(也用于选择)作为起始位置。
RichTextBox控件只使用\n
作为行分隔符,所以我们不用担心\r
.
string searchWord = "John";
var txt = richTextBox1.Text;
int textLenght = txt.Length;
// the indexes list can be created with the alternative method (using IndexOf() in a loop)
var indexes = Regex.Matches(txt, searchWord, RegexOptions.Multiline)
.OfType<Match>()
.Select(m => m.Index).ToList();
foreach (int index in indexes) {
int currentLine = richTextBox1.GetLineFromCharIndex(index);
int lineFirstIndex = richTextBox1.GetFirstCharIndexFromLine(currentLine);
int lineLastIndex = txt.IndexOf("\n", lineFirstIndex);
if (index == lineFirstIndex ||
index == lineLastIndex - searchWord.Length ||
index == textLenght - searchWord.Length) {
richTextBox1.Select(index, searchWord.Length);
richTextBox1.SelectionColor = Color.Red;
}
}
编辑:由于Regex.Matches
不允许,您可以在循环中使用IndexOf()
:
var indexes = new List<int>();
int wordPosition = -1;
do {
if ((wordPosition = txt.IndexOf(searchWord, wordPosition + 1)) >= 0) {
indexes.Add(wordPosition);
}
} while (wordPosition >= 0);
如果搜索到的词在的行首或行尾,我想给它上色。如果它在线的中间则不是彩色的。我尝试了很多东西,但效果不佳。
似乎该行的开头正在运行。但是第一行的结尾只能着色。我想为所有行结束着色。我想我需要每一行开始和循环的索引,但我做不到。
我该如何解决?
private void button1_Click(object sender, EventArgs e)
{
int wordLength = textBox1.Text.Length;
string word = textBox1.Text;
for (int i = 0; i < richTextBox1.Lines.Count(); i++)
{
int startIndex = richTextBox1.GetFirstCharIndexFromLine(i);
richTextBox1.Find(word, startIndex, startIndex+wordLength, RichTextBoxFinds.None);
richTextBox1.SelectionColor = Color.Red;
richTextBox1.SelectionBackColor = Color.Yellow;
int newLineIndex = richTextBox1.Lines[i].Length;
richTextBox1.Find(textBox1.Text, (newLineIndex - wordLength), newLineIndex, RichTextBoxFinds.None);
richTextBox1.SelectionColor = Color.Red;
richTextBox1.SelectionBackColor = Color.Yellow;
}
尝试:
int newLineIndex = i + 1 < richTextBox1.Lines.Length ? richTextBox1.GetFirstCharIndexFromLine(i + 1) - 1 : richTextBox1.TextLength;
我建议稍微更改一下您的代码。当 RichTextBox 文本长度增长时,您会注意到原因。
询问 Lines[]
内容并不是一件好事,在循环中更糟糕,当您可能多次访问此 属性 时。
您可以在 .Net Source Code 中看到发生了什么(每次 - Lines
属性 值未被缓存且不能被缓存)。
GetLineFromCharIndex()
和 GetFirstCharIndexFromLine()
使用 SendMessage
将 EM_LINEFROMCHAR
和 EM_LINEINDEX
消息发送到使用缓存值的编辑控件,并且是相当快。
- 使用
Regex.Matches()
收集匹配词的索引(可以使用多个词,用竖线分隔:"|"
,但这里我们只处理一个词。当匹配多个单词时,使用List<Match>
和Match.Length
而不是searchWord.Length
) 并仅提取每个匹配项的索引位置。 - 然后循环索引,检查当前索引位置是否满足条件。
- 以
IndexOf("\n", [StartPosition])
找到当前行结尾,使用第一行索引(也用于选择)作为起始位置。
RichTextBox控件只使用\n
作为行分隔符,所以我们不用担心\r
.
string searchWord = "John";
var txt = richTextBox1.Text;
int textLenght = txt.Length;
// the indexes list can be created with the alternative method (using IndexOf() in a loop)
var indexes = Regex.Matches(txt, searchWord, RegexOptions.Multiline)
.OfType<Match>()
.Select(m => m.Index).ToList();
foreach (int index in indexes) {
int currentLine = richTextBox1.GetLineFromCharIndex(index);
int lineFirstIndex = richTextBox1.GetFirstCharIndexFromLine(currentLine);
int lineLastIndex = txt.IndexOf("\n", lineFirstIndex);
if (index == lineFirstIndex ||
index == lineLastIndex - searchWord.Length ||
index == textLenght - searchWord.Length) {
richTextBox1.Select(index, searchWord.Length);
richTextBox1.SelectionColor = Color.Red;
}
}
编辑:由于Regex.Matches
不允许,您可以在循环中使用IndexOf()
:
var indexes = new List<int>();
int wordPosition = -1;
do {
if ((wordPosition = txt.IndexOf(searchWord, wordPosition + 1)) >= 0) {
indexes.Add(wordPosition);
}
} while (wordPosition >= 0);