【发布时间】:2018-07-20 12:42:58
【问题描述】:
该类继承 System.Windows.Forms.Label(此控件的最佳功能集)。
控件的大小由基类的 AutoSize 属性设置(必须刚好够用),但 DrawString 画得更宽或更窄,取决于使用的字体。使用大尺寸的字体,高度也可能是错误的。
我推测 Ladel 和 Graphics 使用不同的渲染模式,但无法理解这种差异。
还是代码有问题?
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
【问题讨论】:
-
查看问题需要什么字体类型和大小?
-
Label 控件使用 TextRenderer 类来测量和绘制文本。 Graphics.DrawString 主要用于在纸上打印。 e.ClipRectangle 通常是使用错误的尺寸。
-
@PavlinII 即世高用户界面; 12pt 与文字“快速棕色狐狸跳过懒狗”