문제

I force wrap some of my text. The following method is used in a loop when I do this; it returns the Y cord for the next line (based on the string height). This works like a charm, however I lose the ability to center the text vertically.

I'm looking for suggestions on how to enhance this method to allow for vertical centering.

 <Extension()> _
        Public Function DrawText(ByVal p_graphics As Graphics, ByVal p_text As String, ByVal p_Font As Font, ByVal p_fontColor As Brush, ByVal p_X As Decimal, ByVal p_Y As Decimal, _
                                 ByVal p_boundingWidth As Decimal, ByVal p_StringFormat As StringFormat) As Decimal

            If String.IsNullOrEmpty(p_text) Then
                Return p_Y
            End If

            Dim _sizef As SizeF = p_graphics.MeasureString(p_text, p_Font, Integer.MaxValue, p_StringFormat)
            Dim _LineCnt As Integer = Math.Ceiling(_sizef.Width / p_boundingWidth)
            Dim _height As Integer = Math.Ceiling(_LineCnt * Math.Ceiling(_sizef.Height))

            p_graphics.TextRenderingHint = Drawing.Text.TextRenderingHint.AntiAliasGridFit
            Dim _rec As New RectangleF(p_X, p_Y, p_boundingWidth, _height)
            p_graphics.DrawString(p_text, p_Font, p_fontColor, _rec, p_StringFormat)
            Return (p_Y + _rec.Height)
        End Function

Example of how I use this extension method (writing this free hand so syntax may not be correct):

.
.
.
    Using g as graphics.FromImage(_MyImage)
        Dim _LineStart as integer = 0
        Foreach _line as string in _Lines 'List of String
         _LineStart = g.DrawText(line, _font, Obj.FontColorBrush, 0, _LineStart, Obj.DPIWidth, Obj.StringFormat)
        End For
    End Using
.
.
.
도움이 되었습니까?

해결책

OK, now I think I understand. You need to calculate where to start drawing vertically.

I put a PictureBox and a Button on a form, added your extension method, and used this code:

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim lines As New List(Of String)
    lines.Add("The quick brown")
    lines.Add("fox jumps over")
    lines.Add("the lazy dog.")
    lines.Add("This line is too wide to fit the available space.")

    Dim fmt = StringFormat.GenericTypographic
    fmt.Alignment = StringAlignment.Center

    Using fnt = New Font("Arial", 8)
        Using brsh = New SolidBrush(Color.Black)
            Using g = PictureBox1.CreateGraphics

                Dim lineY As Integer = (PictureBox1.Height - lines.Count * fnt.Height) \ 2

                For Each line As String In lines
                    lineY = CInt(g.DrawText(line, fnt, brsh, 0, lineY, PictureBox1.Width, fmt))
                Next

            End Using
        End Using
    End Using

End Sub

Example result

As I use Option Strict On, I had to make some minor modifications to your DrawText method.

Note how the line which is too long is truncated. Centred, but truncated. That is where you might want to use the Graphics.MeasureString Method (String, Font, SizeF, StringFormat) overload so that you have the possibility of it wrapping automatically. Which will of course mess up the calculation for the vertical centring.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top