WinForm下RichTextBox行首关键词无法高亮的问题及修改建议
VB.NET WinForm RichTextBox 行首关键词高亮问题解决思路
你提到用了YouTube上的代码,整体运行正常,但第二行及以后的行首关键词(比如Hello、Dinesh)没法高亮,而且不想引入FastColoredTextBox这类组件,想基于现有简单实现修改。我来帮你拆解问题并给出解决方案:
问题根源
原代码的循环终止条件只判断了空格和文本起始位置(SelectionStart=0),但行首的关键词前面是换行符(\r\n),不是空格,所以循环会一直跑到整个文本的起始位置(而不是当前行的行首),导致无法正确选中行首的关键词,自然没法高亮。
原代码(供参考)
If e.KeyCode = Keys.Space Or e.KeyCode = Keys.Back Or e.KeyCode = Keys.Enter Then Dim selectionlength As Integer = RichTextBox1.SelectionLength Dim selectionstart As Integer = RichTextBox1.SelectionStart Dim letter As String = String.Empty Do Until letter = " " Or RichTextBox1.SelectionStart = 0 RichTextBox1.SelectionStart -= 1 RichTextBox1.SelectionLength += 1 letter = RichTextBox1.Text.Substring(RichTextBox1.SelectionStart, 1) Loop If RichTextBox1.SelectedText = "Hello" Or RichTextBox1.SelectedText = " Hello" Then RichTextBox1.SelectionColor = Color.HotPink ElseIf RichTextBox1.SelectedText = "Dinesh" Or RichTextBox1.SelectedText = " Dinesh" Then RichTextBox1.SelectionColor = Color.Peru Else RichTextBox1.SelectionColor = Color.White End If RichTextBox1.SelectionStart = selectionstart RichTextBox1.SelectionLength = 0 RichTextBox1.SelectionColor = Color.White End If
修改后的VB.NET代码
If e.KeyCode = Keys.Space Or e.KeyCode = Keys.Back Or e.KeyCode = Keys.Enter Then Dim selectionlength As Integer = RichTextBox1.SelectionLength Dim selectionstart As Integer = RichTextBox1.SelectionStart Dim letter As String = String.Empty ' 修改循环终止条件:增加换行符判断(\r 和 \n) Do Until letter = " " Or letter = vbCr Or letter = vbLf Or RichTextBox1.SelectionStart = 0 RichTextBox1.SelectionStart -= 1 RichTextBox1.SelectionLength += 1 ' 防止SelectionStart为0时越界 If RichTextBox1.SelectionStart = 0 Then letter = RichTextBox1.Text.Substring(0, 1) Else letter = RichTextBox1.Text.Substring(RichTextBox1.SelectionStart, 1) End If Loop Dim selectedText As String = RichTextBox1.SelectedText.TrimStart(vbCr, vbLf) ' 去掉可能的前置换行符 ' 判断时同时覆盖行首(无前置空格)和中间(带前置空格)的情况 If selectedText.Equals("Hello", StringComparison.Ordinal) Or selectedText.Equals(" Hello", StringComparison.Ordinal) Then RichTextBox1.SelectionColor = Color.HotPink ElseIf selectedText.Equals("Dinesh", StringComparison.Ordinal) Or selectedText.Equals(" Dinesh", StringComparison.Ordinal) Then RichTextBox1.SelectionColor = Color.Peru Else RichTextBox1.SelectionColor = Color.White End If RichTextBox1.SelectionStart = selectionstart RichTextBox1.SelectionLength = 0 RichTextBox1.SelectionColor = Color.White End If
对应的C#版本
如果你需要C#版本,代码如下:
if (e.KeyCode == Keys.Space || e.KeyCode == Keys.Back || e.KeyCode == Keys.Enter) { int selectionLength = richTextBox1.SelectionLength; int selectionStart = richTextBox1.SelectionStart; string letter = string.Empty; // 修改循环终止条件:增加换行符判断 while (!(letter == " " || letter == "\r" || letter == "\n" || richTextBox1.SelectionStart == 0)) { richTextBox1.SelectionStart--; richTextBox1.SelectionLength++; // 防止越界 letter = richTextBox1.SelectionStart == 0 ? richTextBox1.Text.Substring(0, 1) : richTextBox1.Text.Substring(richTextBox1.SelectionStart, 1); } string selectedText = richTextBox1.SelectedText.TrimStart('\r', '\n'); // 判断关键词 if (selectedText.Equals("Hello", StringComparison.Ordinal) || selectedText.Equals(" Hello", StringComparison.Ordinal)) { richTextBox1.SelectionColor = Color.HotPink; } else if (selectedText.Equals("Dinesh", StringComparison.Ordinal) || selectedText.Equals(" Dinesh", StringComparison.Ordinal)) { richTextBox1.SelectionColor = Color.Peru; } else { richTextBox1.SelectionColor = Color.White; } richTextBox1.SelectionStart = selectionStart; richTextBox1.SelectionLength = 0; richTextBox1.SelectionColor = Color.White; }
关键修改点说明
- 循环终止条件扩展:增加了对
vbCr(回车符)和vbLf(换行符)的判断,这样碰到换行时就会停止循环,正确选中当前行的行首关键词。 - 选中文本处理:用
TrimStart去掉选中文本中可能带的前置换行符,避免判断时因为换行符导致匹配失败。 - 越界防护:增加了SelectionStart为0时的字符串截取判断,防止出现索引越界异常。
这样修改后,不管关键词在文本开头、中间还是新行的行首,都能被正确识别并高亮了。
内容的提问来源于stack exchange,提问作者Dr. Pacific Oceans
相关产品推荐
相关产品推荐

