Подсветка синтаксиса VB.NET в текстовом поле с форматированным текстом
-
08-07-2019 - |
Вопрос
Я пишу простой редактор кода для очень простого языка сценариев, который мы используем на работе.Мой код подсветки синтаксиса работает нормально, если я делаю это по всему RichTextBox
(rtbMain
), но когда я пытаюсь заставить его работать только с этой строкой, я могу запустить функцию с помощью rtbMain
меняется, это становится странным.Я не могу понять, почему.Правильно ли я это делаю?
rtbMain
это основное текстовое поле.frmColors.lbRegExps
— это список слов, которые нужно выделить (позже в нем появятся более мощные регулярные выражения.)frmColor.lbHexColors
это еще один список с соответствующими шестнадцатеричными цветами для слов.
Private Sub HighLight(ByVal All As Boolean)
Dim RegExp As System.Text.RegularExpressions.MatchCollection
Dim RegExpMatch As System.Text.RegularExpressions.Match
Dim FirstCharIndex As Integer = rtbMain.GetFirstCharIndexOfCurrentLine
Dim CurrentLine As Integer = rtbMain.GetLineFromCharIndex(FirstCharIndex)
Dim CurrentLineText As String = rtbMain.Lines(CurrentLine)
Dim CharsToCurrentLine As Integer = rtbMain.SelectionStart
Dim PassNumber As Integer = 0
LockWindowUpdate(Me.Handle.ToInt32) 'Let's lock the window so it doesn't scroll all crazy.
If All = True Then 'Highlight everything.
For Each pass In frmColors.lbRegExps.Items
RegExp = System.Text.RegularExpressions.Regex.Matches(LCase(rtbMain.Text), LCase(pass))
For Each RegExpMatch In RegExp
rtbMain.Select(RegExpMatch.Index, RegExpMatch.Length)
rtbMain.SelectionColor = ColorTranslator.FromHtml(frmColors.lbHexColors.Items(PassNumber))
Next
PassNumber += 1
Next
Else 'Highlight just that row.
For Each pass In FrmColors.lbRegExps.Items
RegExp = System.Text.RegularExpressions.Regex.Matches(LCase(CurrentLineText), LCase(pass))
For Each RegExpMatch In RegExp
rtbMain.Select(RegExpMatch.Index + (CharsToCurrentLine - RegExpMatch.Length), RegExpMatch.Length)
rtbMain.SelectionColor = Color.Blue
Next
Next
End If
rtbMain.Select(CharsToCurrentLine, 0) 'Reset colors and positon and then unlock drawing.
rtbMain.SelectionColor = Color.Black
LockWindowUpdate(0)
End Sub
Решение
Хорошо, я понял это.Я вызывал событие rtbMain.TextChange, думая, что это сработает только в том случае, если текст действительно изменится.Нет, нет, это также сработает, если форматирование будет изменено.поэтому каждый раз, когда он что-то менял во время первого прохода и выделения всего, он затем запускал выделение строки.Так будет до тех пор, пока не останется ничего, что можно было бы изменить.
Я установил логическую переменную для погоды или нет, она в данный момент подсвечивалась, и добавил условие if внутри подпрограммы TextChange.
P.S.У меня нет значка самообучающегося, поэтому любые оценки будут приветствоваться :P
Другие советы
Это на самом деле не отвечает на ваш вопрос, но если вы пишете свой собственный редактор, вам лучше использовать некоторую существующую работу с открытым исходным кодом, которая была сделана для .NET. Я бы порекомендовал:
SyntaxBox Роджера Алсинга
Private Sub HighLight(ByVal All As Boolean)
Dim RegExp As System.Text.RegularExpressions.MatchCollection
Dim RegExpMatch As System.Text.RegularExpressions.Match
Dim FirstCharIndex As Integer = rtbMain.GetFirstCharIndexOfCurrentLine
Dim CurrentLine As Integer = rtbMain.GetLineFromCharIndex(FirstCharIndex)
Dim CurrentLineText As String = rtbMain.Lines(CurrentLine)
Dim CharsToCurrentLine As Integer = rtbMain.SelectionStart
Dim PassNumber As Integer = 0
LockWindowUpdate(Me.Handle.ToInt32) ''lets lock the window so it doesnt scroll all crazy
If All = True Then ''highlight everything
For Each pass In frmColors.lbRegExps.Items
RegExp = System.Text.RegularExpressions.Regex.Matches(LCase(rtbMain.Text), LCase(pass))
For Each RegExpMatch In RegExp
rtbMain.Select(RegExpMatch.Index, RegExpMatch.Length)
rtbMain.SelectionColor = ColorTranslator.FromHtml(frmColors.lbHexColors.Items(PassNumber))
Next
PassNumber += 1
Next
Else ''higlight just that row
For Each pass In FrmColors.lbRegExps.Items
RegExp = System.Text.RegularExpressions.Regex.Matches(LCase(CurrentLineText), LCase(pass))
For Each RegExpMatch In RegExp
rtbMain.Select(RegExpMatch.Index + (CharsToCurrentLine - RegExpMatch.Length), RegExpMatch.Length)
rtbMain.SelectionColor = Color.Blue
Next
Next
End If
rtbMain.Select(CharsToCurrentLine, 0) ''reset colors and positon and then unlock drawing
rtbMain.SelectionColor = Color.Black
LockWindowUpdate(0)
End Sub