2

I need to loop through each character of the selected text in a rich text box applying a font aspect (family, size, or style) to each character. This aspect is selected using a font dialogue box. I do not want to introduce any other types of dialog box (e.g. color dialogue) into this code.

So far I have tentatively got the following which may well be wrong:

If aFontDialog.ShowDialog = Windows.Forms.DialogResult.OK Then
    If rtb.SelectionFont IsNot Nothing Then
        rtb.SelectionFont = aFontDialog.Font
        rtb.SelectionColor = aFontDialog.Color
    Else
        For index As Integer = 0 To rtb.SelectionLength - 1
           '<<????
        Next
    End If
End If

EDIT

This article on CodeProject explains the problem better than I can www.codeproject.com...

whytheq
  • 34,466
  • 65
  • 172
  • 267
  • That is going to flicker like mad. – LarsTech Mar 01 '13 at 23:33
  • 1
    Why are you applying the same font on each character rather than on the selection itself? – VDALLCO Mar 02 '13 at 00:33
  • I am with @Cody on this one. Apply new font once on the whole selection. – Victor Zakharov Mar 02 '13 at 00:59
  • @Neolisk That won't work right if the selection range is a combination of different font styles. A weakness of the RichTextBox control in WinForms. – LarsTech Mar 02 '13 at 01:02
  • @LarsTech: you mean if just set SelectionFont of the whole selection, nothing happens? – Victor Zakharov Mar 02 '13 at 01:04
  • @Neolisk If you have a combination of different font names and a mixture of bold and italic, etc, the SelectionFont will overwrite all that with the new font. The ugly work around is to go character by character and just modify the font for each character, or through pinvoke. – LarsTech Mar 02 '13 at 02:48
  • @LarsTech In my example I can use any font as long as it's a true font. You can mix colors and styles anyway you want to, it works fine for me. – Trevor Mar 02 '13 at 05:42
  • Also you can select whatever part of the text you want and change color and font then select another piece of it and change its color and font; it works for me great... – Trevor Mar 02 '13 at 05:49
  • @LarsTech "The ugly work around is to go character by character and just modify the font for each character" this is exactly what I'm trying to do - have a look at my other question [HERE ON SO](http://stackoverflow.com/questions/15167422/for-a-rich-text-box-i-need-to-amend-the-font-of-current-selection-if-it-contains). If you have a reference to an article that explains this character by character work around then just that reference would be the correct answer to both these questions! – whytheq Mar 02 '13 at 09:10
  • @LarsTech: `SelectionFont will overwrite all that with the new font`, is it not what OP wants? I am still not getting why you need to go character by character. – Victor Zakharov Mar 02 '13 at 12:33

2 Answers2

2

For your request for the ugly method, here it is:

To make a selection bold (while preserving any italics or underlines, etc):

Dim startIndex As Integer = rtb.SelectionStart
Dim textLength As Integer = rtb.SelectionLength
For i As Integer = startIndex To startIndex + textLength - 1
  rtb.Select(i, 1)
  rtb.SelectionFont = New Font(rtb.SelectionFont, _
                               rtb.SelectionFont.Style Or FontStyle.Bold)
Next
rtb.Select(startIndex, textLength)

To remove the bold, change the line above to this:

rtb.SelectionFont = New Font(rtb.SelectionFont, _
                             rtb.SelectionFont.Style And Not FontStyle.Bold)

If working on a large document, there will be considerable flicker. In that case, you need to turn off the drawing of the control until you finish formatting, see RichTextBox syntax highlighting in real time--Disabling the repaint.

Instead of iterating through the characters one by one, you can also do this through pinvoke. Here is a random project at Code Project that shows the basics: Richer RichTextBox (Part 1)

I don't believe the WPF RichTextBox has these limitations, so that would be another option to look at, if possible.

Community
  • 1
  • 1
LarsTech
  • 80,625
  • 14
  • 153
  • 225
0

Here this works when double clicking a string within the rich textbox area...

 Private Sub rtb_DoubleClick(sender As Object, e As System.EventArgs) Handles rtb.DoubleClick
    If ColorDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
        If rtb.SelectionFont IsNot Nothing Then
           rtb.SelectionColor = ColorDialog1.color
        End If
    End If

    If FontDialog1.ShowDialog = Windows.Forms.DialogResult.OK Then
        rtb.SelectionFont = FontDialog1.Font
    End If
  End Sub

This will apply the color and text style to whatever string you double click on in the richtextbox area....

Trevor
  • 7,777
  • 6
  • 31
  • 50
  • please refer to `OP` - I'm using the `fontDialog` _not_ a colorDialog. Also why do you repeat the line `rtb.SelectionColor = ColorDialog1.Color` in the `IF` statement? – whytheq Mar 02 '13 at 09:14
  • have you tested your answer on a string that is multi-coloured i.e the first 5 characters are red and the rest are blue?....that is the situation I'm working on – whytheq Mar 02 '13 at 09:32
  • if the first half of the string is in consolas and the second half is in lucida sans but all I want to do is change the size to 20 then this solution fails as all the characters will be forced into one font – whytheq Mar 02 '13 at 09:39
  • .....see LarsTech's comment above - somehow we need to go from character to character applying the new font aspect and preserving everything else - just don't know how to implement this! – whytheq Mar 02 '13 at 09:41
  • I've tested this well enough. You can select any part of the string and change anything(color,size & font). It will change, have you tried it? Also if its just the font your using then take out the if statement for color. You don't need to go character to character as when you select a string to change, the changes only apply to the selected text. – Trevor Mar 02 '13 at 14:35
  • ok - the reason for the question is that several aspects of the font might be mixed up in the selected text - so your solution will not work - I will amend the OP later today so you can see what I mean. – whytheq Mar 03 '13 at 08:28
  • ...ok the reference that LarsTech added has been added to the OP - it explains the problem more fully than I ever could. – whytheq Mar 07 '13 at 21:11