Reputation: 168
The class inherits System.Windows.Forms.Label (best set of features for this control).
Size of control are set by AutoSize property of the base class (must be just enough), but the DrawString draws little wider or narrower, depends on the used font. With big sizes of font, height can be wrong too.
I presume that Ladel and Graphics use different modes of rendering, but can not understand this differences.
Or it is something wrong with the code?
Public Class LabelProgressBar
Inherits Label
Private dProgress As Double = 0.0
Private nBackAlpha As Byte = 64
Private stBarColor0 As Color = Color.Maroon
Private stBarColor1 As Color = Color.ForestGreen
Public Property BackAlpha As Byte
Get
Return nBackAlpha
End Get
Set(value As Byte)
If value <> nBackAlpha Then
nBackAlpha = value
Invalidate()
End If
End Set
End Property
Public Property BarColor0 As Color
Get
Return stBarColor0
End Get
Set(value As Color)
If value <> stBarColor0 Then
stBarColor0 = value
Invalidate()
End If
End Set
End Property
Public Property BarColor1 As Color
Get
Return stBarColor1
End Get
Set(value As Color)
If value <> stBarColor1 Then
stBarColor1 = value
Invalidate()
End If
End Set
End Property
Public Property Progress As Double
Get
Return dProgress
End Get
Set(value As Double)
If value <> dProgress Then
Dim fOld = InnerProgress
dProgress = value
If InnerProgress <> fOld Then Invalidate()
End If
End Set
End Property
Private ReadOnly Property InnerProgress As Single
Get
If dProgress < 0.0 Then Return 0.0
If dProgress > 1.0 Then Return 1.0
Return CSng(Progress)
End Get
End Property
Private Sub LabelProgressBar_PaddingChanged(sender As Object, e As EventArgs) Handles Me.PaddingChanged
Invalidate()
End Sub
Private Sub LabelProgressBar_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
If Width - Padding.Left - Padding.Right > 0 AndAlso Height - Padding.Top - Padding.Bottom > 0 Then
e.Graphics.CompositingQuality = CompositingQuality.HighQuality
e.Graphics.TextRenderingHint = Drawing.Text.TextRenderingHint.ClearTypeGridFit
e.Graphics.Clear(BackColor)
PaintGradient(e.Graphics, e.ClipRectangle, 1.0, nBackAlpha)
PaintGradient(e.Graphics, e.ClipRectangle, InnerProgress, 255)
Dim stNonPadded = New RectangleF(e.ClipRectangle.Location, e.ClipRectangle.Size)
stNonPadded.X = Padding.Left
stNonPadded.Width -= Padding.Left + Padding.Right
stNonPadded.Y = Padding.Top
stNonPadded.Height -= Padding.Top + Padding.Bottom
Using objBrush = New SolidBrush(ForeColor)
Using objFormat = New StringFormat()
Select Case TextAlign
Case ContentAlignment.TopLeft, ContentAlignment.MiddleLeft, ContentAlignment.BottomLeft
objFormat.Alignment = StringAlignment.Near
Case ContentAlignment.TopCenter, ContentAlignment.MiddleCenter, ContentAlignment.BottomCenter
objFormat.Alignment = StringAlignment.Center
Case Else
objFormat.Alignment = StringAlignment.Far
End Select
objFormat.Trimming = If(AutoEllipsis, StringTrimming.EllipsisWord, StringTrimming.Character)
Select Case TextAlign
Case ContentAlignment.MiddleLeft, ContentAlignment.MiddleCenter, ContentAlignment.MiddleRight
Dim stDrawSize = e.Graphics.MeasureString(Text, Font, stNonPadded.Size, objFormat)
stNonPadded.Y += (stNonPadded.Height - stDrawSize.Height) / 2
Case ContentAlignment.BottomLeft, ContentAlignment.BottomCenter, ContentAlignment.BottomRight
Dim stDrawSize = e.Graphics.MeasureString(Text, Font, stNonPadded.Size, objFormat)
stNonPadded.Y += stNonPadded.Height - stDrawSize.Height
End Select
e.Graphics.DrawString(Text, Font, objBrush, stNonPadded, objFormat)
End Using
End Using
End If
End Sub
Private Sub LabelProgressBar_TextAlignChanged(sender As Object, e As EventArgs) Handles Me.TextAlignChanged
Invalidate()
End Sub
Private Sub PaintGradient(surface As Graphics, bounds As Rectangle, progress As Single, alpha As Byte)
Dim stColor0 = Color.FromArgb(alpha, stBarColor0)
Dim stColor1 = Color.FromArgb(alpha, stBarColor1)
Using objBrush = New LinearGradientBrush(bounds, stColor0, stColor1, LinearGradientMode.Horizontal)
surface.FillRectangle(objBrush, New RectangleF(bounds.Left, bounds.Top, bounds.Width * progress, bounds.Height))
End Using
End Sub
End Class
Upvotes: 0
Views: 57
Reputation: 1083
Why don't you let the label to do the drawstring job for you?
Protected Overrides Sub OnPaintBackground(e As PaintEventArgs)
MyBase.OnPaintBackground(e)
If Width - Padding.Left - Padding.Right > 0 AndAlso Height - Padding.Top - Padding.Bottom > 0 Then
e.Graphics.CompositingQuality = Drawing2D.CompositingQuality.HighQuality
e.Graphics.TextRenderingHint = Drawing.Text.TextRenderingHint.ClearTypeGridFit
e.Graphics.Clear(BackColor)
PaintGradient(e.Graphics, e.ClipRectangle, 1.0, nBackAlpha)
PaintGradient(e.Graphics, e.ClipRectangle, InnerProgress, 255)
End If
End Sub
MeasureString/DrawString is little more complicated than you would expect. I can see the last character beeing stripped (not rendered) when DrawString with rectangle argument is used. You can avoid this by using this line
e.Graphics.DrawString(Text, Font, objBrush, stNonPadded.Location, objFormat)
but I'm not sure if that's your problem since your description was not very clear about it.
Also align according to ClipRectangle is not good idea since it can be half of your control when form is moving, hidden, partially hidden, moved out of the screen and so on.
Upvotes: 1