Evidenziazione della sintassi VB.NET in una casella di testo RTF
-
08-07-2019 - |
Domanda
Sto codificando un semplice editor di codice per un linguaggio di scripting molto semplice che usiamo al lavoro. Il mio codice di evidenziazione della sintassi funziona bene se lo faccio sull'intero RichTextBox
( rtbMain
) ma quando provo a farlo funzionare solo su quella linea, quindi posso eseguire il funziona con le modifiche rtbMain
, diventa strano. Non riesco a capire perché. Sto anche andando nel modo giusto?
rtbMain
è la casella di testo principale.
frmColors.lbRegExps
è una lista di parole da evidenziare (in seguito avrà espressioni regolari leggermente più potenti.)
frmColor.lbHexColors
è un'altra casella di riepilogo con i colori esadecimali corrispondenti per le parole.
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
Soluzione
Ok, l'ho capito. Stavo chiamando the even su rtbMain.TextChange pensando che questo si innescherebbe solo se il testo fosse effettivamente cambiato. No, si attiverà anche se la formattazione viene modificata. così ogni volta che cambiava qualcosa mentre stava facendo il suo primo passaggio ed evidenziando tutto, si innescherebbe per evidenziare la linea. Lo farebbe fino a quando non sarebbe rimasto più nulla da cambiare.
Ho impostato una variabile booleana per il tempo o meno che stava evidenziando e ho aggiunto una condizione if all'interno del sottotitolo TextChange
P.S. Non ho il badge autodidatta, quindi qualsiasi valutazione positiva sarebbe benvenuta: P
Altri suggerimenti
Questo non risponde davvero alla tua domanda, ma se stai scrivendo il tuo editor potresti essere meglio usando un lavoro open source esistente che è stato fatto per .NET. Consiglierei:
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