Search code examples
vb.netrichtextboxfont-style

Change Font Style on All Instances of a String in a RichTextBox


I'm working on a VB.NET 4.5 project in VS2013.

I have a richtextbox on a form and when a button is clicked I need to toggle the BOLD setting on all instances of a specific string found in the richtextbox.

I put together some code based on this question.

Private Sub ToggleBold()

    rtxtOutputText.SelectionStart = rtxtOutputText.Find("@#$%", RichTextBoxFinds.None)

    rtxtOutputText.SelectionFont = New Font(rtxtOutputText.Font, FontStyle.Bold)
End Sub

However when the toggle bold button is clicked it only bolds the first instance of the string "@#$%".

How can I set all instances of the string to bold? There can also be several of them strung together ("@#$%@#$%@#$%"), so each of those would need to be bolded too.

(I know I mentioned toggling bold, but I'll set up the toggle portion later, right now I'm just trying to get the bold on all instances working right...)


Solution

  • Just add a loop to it and use the RichTextBox.Find(String, Int32, RichTextBoxFinds) overload to specify from where to start looking. Look from the current index + 1 so that it doesn't return the same again.

    You also ought to actually select the word as well, so that you're sure the bold applies to the current instance only and not the text around it.

    Private Sub ToggleBold()
        'Stop the control from redrawing itself while we process it.
        rtxtOutputText.SuspendLayout()
    
        Dim LookFor As String = "@#$%"
        Dim PreviousPosition As Integer = rtxtOutputText.SelectionStart
        Dim PreviousSelection As Integer = rtxtOutputText.SelectionLength
        Dim SelectionIndex As Integer = -1
    
        Using BoldFont As New Font(rtxtOutputText.Font, FontStyle.Bold)
            While True
                SelectionIndex = rtxtOutputText.Find(LookFor, SelectionIndex + 1, RichTextBoxFinds.None)
    
                If SelectionIndex < 0 Then Exit While 'No more matches found.
    
                rtxtOutputText.SelectionStart = SelectionIndex
                rtxtOutputText.SelectionLength = LookFor.Length
    
                rtxtOutputText.SelectionFont = BoldFont
            End While
        End Using
    
        'Allow the control to redraw itself again.
        rtxtOutputText.ResumeLayout()
    
        'Restore the previous selection.
        rtxtOutputText.SelectionStart = PreviousPosition
        rtxtOutputText.SelectionLength = PreviousSelection
    End Sub
    

    Credit to Plutonix for telling me to dispose the font.