How to wrap long word with TextRenderer DrawText in vb.net

2k Views Asked by At

How can I draw a long word on a form with word breaking using TextRenderer DrawText() in vb.net? I thought it's a simple question and I tried all TextFormatFlags combinations but I can't find nothing solution. Can anyone help? Here is a sample:

sText = "C:\Users\abiga\OneDrive\Works\AdreNDSzinkron\bin\Debug\AdreService.exe"
TextRenderer.DrawText(e.Graphics, sText, Font, New Rectangle(0, 0, Me.Width, Me.Height),
                      Me.Color,TextFormatFlags.<what is the correct flag?>) 

I need this (nothing clipped):

C:\Users\abiga\OneDrive\Works\Adr
eNDSzinkron\bin\Debug\AdreService
.exe

Wrong solutions:

C:\Users\abiga\OneDrive\Works\Adr
C:\Users\abiga\OneDrive\Works\...
C:\Users\ab...bug\AdreService.exe

Thank you for your help!

2

There are 2 best solutions below

3
On BEST ANSWER

First try TextFormatFlags.WordBreak or TextFormatFlags.TextBoxControl as your flags.

The docs say:

WordBreak: Breaks the text at the end of a word

TextBoxControl: Specifies the text should be formatted for display on a TextBox control

Combining these flags should give the expected result.

If that doesnt work then try using Graphics.DrawString instead:

e.Graphics.DrawString(sText, Font, Me.Color, New RectangleF(0, 0, Me.Width, Me.Height))

3
On

Just to add some implementation details that can be used to evaluate the differences between TextRenderer's DrawText() method and the Graphics's DrawString() method.

Clicking on the Form, the two methods show their differences in measuring and rendering the text.

Dim sText As String() = New String() {
    "C:\FirstLevelDir\FirstSubDir\AnotherDir\ADeepLevelDir\LostDeepDir\SomeFile.exe",
    "C:\FirstLevelDir\AnotherFirstSubDir\AnotherGreatDir\AwsomeDeepLevelDir\LostDeepDir\Some.exe",
    "C:\FirstLevelDir\SomeFirstSubDir\SomeOtherDir\AnotherDeepLevelDir\VeryLostDeepDir\FinalBuriedDir\SomeFile.exe"
}

In the Form's Click() event, draw sText lines, measuring their Width and Height using TextRenderer.MeasureText() and print them with TextRenderer.DrawText()

Private Sub Form1_Click(sender As Object, e As EventArgs) Handles Me.Click
    Dim relPositionY As Integer = 0
    Dim lineSpacing As Single = 0.5
    Dim paragraphSpacing As Integer = CInt(Font.Height * lineSpacing)

    Dim flags As TextFormatFlags = TextFormatFlags.Top Or
                                   TextFormatFlags.WordBreak Or 
                                   TextFormatFlags.TextBoxControl

     Using g As Graphics = CreateGraphics()
         For x = 0 To sText.Length - 1
             Dim textSize As Size = TextRenderer.MeasureText(
                 g, sText(x), Font,
                 New Size(ClientSize.Width, ClientSize.Height), flags
             )

             TextRenderer.DrawText(g, sText(x), Font,
                 New Rectangle(0, relPositionY, textSize.Width, textSize.Height),
                 ForeColor, flags)
             relPositionY += textSize.Height + paragraphSpacing
         Next
     End Using
End Sub

In the Form's Paint() event, draw sText lines, measuring their Width and Height using .Graphics.MeasureString() and print them with .Graphics.DrawString()

Note that the text boxed size in TextRenderer is relative to the Form.ClientSize, while in Graphics is relative to the Form's full Width.

Private Sub Form1_Paint(sender As Object, e As PaintEventArgs) Handles MyBase.Paint
    Dim relPositionY As Single = 0
    Dim lineSpacing As Single = 0.5
    Dim paragraphSpacing As Single = CSng(Font.Height) * lineSpacing

    Dim flags As StringFormatFlags = StringFormatFlags.LineLimit Or
                                     StringFormatFlags.FitBlackBox

    Using format As StringFormat = New StringFormat(flags)
        For x = 0 To sText.Length - 1
            Dim textSize As SizeF = e.Graphics.MeasureString(sText(x), Font,
                New SizeF(CSng(Width), CSng(Height)), format
            )
            e.Graphics.DrawString(sText(x), Font, Brushes.Black,
                New RectangleF(0, relPositionY, textSize.Width, textSize.Height))
            relPositionY += textSize.Height + paragraphSpacing
        Next
    End Using
End Sub