带百分比的进度条






4.48/5 (21投票s)
此组件扩展了原生的 .NET 进度条,增加了百分比属性,并可在进度条中显示百分比。


引言
这个类扩展了原生的 .NET 进度条,增加了一个百分比属性,可以在进度条内部显示,用于获取或设置进度条本身的值。文本可以通过 Alignment
属性对齐,并且具有 Font
和 Padding
属性以允许进一步的自定义。最重要的是,您可以更改进度条彩色部分中百分比的颜色。
你可能会问,为什么又有一个进度条控件?很简单。在创建此控件之前,我做了很多研究,希望能找到一个能够在进度条中显示百分比的控件。大多数控件都成功地实现了这一点,具有不同程度的自定义选项,并且在 Windows XP 中运行良好。但是,一旦在 Vista 上使用,百分比就会被删除,因为进度条会不断重绘自身。此控件将在进度条刷新时自动重绘百分比。
背景
这个类包含了许多基于 VB.NET 论坛上人们的工作的代码。前往 此线程 获取更多信息。我正在多个 VB.NET 应用程序中使用此组件,没有任何问题,它应该可以在其他 .NET 语言的项目中使用。
Using the Code
将此类添加到您的项目后,您应该能够使用设计器将新组件添加到您的窗体,或者使用代码手动完成。
这里是已添加属性的概述
<Browsable(True), Category("Appearance"), _
Description("The percentage of the progressbar")> _
Public Property Percentage() As Double
Get
Return Me.Value / Me.Maximum * 100
End Get
Set(ByVal value As Double)
If value >= 0 And value <= 100 Then
Me.Value = CInt(Me.Maximum * value / 100)
If Me.PercentageVisible And Me.AutoUpdatePercentage _
Then Me.ShowPercentage()
End If
End Set
End Property
<Browsable(True), Category("Appearance"), DefaultValue(0), _
Description("Gets or sets the amount of decimals that will _
be displayed in the percentage")> _
Public Overridable Property PercentageDecimals() As Int32
Get
Return m_decimals
End Get
Set(ByVal value As Int32)
If value > -1 Then m_decimals = value
End Set
End Property
<Browsable(True), Category("Appearance"), DefaultValue(True), _
Description("Gets or sets if the percentage should be visible")> _
Public Overridable Property PercentageVisible() As Boolean
Get
Return m_p_visible
End Get
Set(ByVal value As Boolean)
If value <> Me.PercentageVisible Then
If Not value Then Me.Graphics.Clear(Color.Transparent)
m_p_visible = value
RaiseEvent PercentageVisibleChanged(Me, New EventArgs)
End If
End Set
End Property
<Browsable(True), Category("Appearance"), DefaultValue("MiddleCenter"), _
Description("Gets or sets if the percentage alignment")> _
Public Overridable Property PercentageAlign() As ContentAlignment
Get
Return m_p_align
End Get
Set(ByVal value As ContentAlignment)
m_p_align = value
End Set
End Property
<Browsable(True), Category("Appearance"), _
Description("Gets or sets the color of the percentage text _
at the place of the progressbar that is indicated")> _
Public Overridable Property OverLayColor() As Color
Get
Return m_overLayFont
End Get
Set(ByVal value As Color)
m_overLayFont = value
End Set
End Property
<Browsable(True), Category("Behavior"), DefaultValue(True), _
Description("Gets or sets if the percentage should be auto updated")> _
Public Overridable Property AutoUpdatePercentage() As Boolean
Get
Return m_auto_update
End Get
Set(ByVal value As Boolean)
m_auto_update = value
End Set
End Property
<Browsable(True), Category("Layout"), _
Description("Gets or sets if the interior spacing of the control")> _
Public Overridable Overloads Property Padding() As Padding
Get
Return MyBase.Padding
End Get
Set(ByVal value As Padding)
MyBase.Padding = value
End Set
End Property
<Browsable(True), Category("Appearance"), _
Description("Gets or sets the font of the percentage text")> _
Public Overridable Overloads Property Font() As Font
Get
Return MyBase.Font
End Get
Set(ByVal value As Font)
MyBase.Font = value
End Set
End Property
示例
一个设置几个属性的简单例子
With Me.ProgressbarWithPercentage1
.ForeColor = Drawing.Color.DimGray ' Color of the text not in the colored part
.OverLayColor = Drawing.Color.Black ' Color of the text in the colored part
.PercentageAlign = Drawing.ContentAlignment.MiddleLeft ' Alignment of the text
.Padding = New Windows.Forms.Padding(20, 0, 0, 0) ' Padding of the text
End With
组件内部
现在它是如何实际工作的呢?我将尝试给您一个合理的理解。
最重要的函数是 ShowText
函数,它将一个 string
绘制到进度条上。此函数可以用于绘制任何 string
,但在内部仅用于绘制百分比。
Public Sub ShowText(ByVal text As String)
' Determine the areas for the ForeColor and OverlayColor
Dim r1 As RectangleF = Me.ClientRectangle
r1.Width = CSng(r1.Width * Me.Value / Me.Maximum)
Dim reg1 As New Region(r1)
Dim reg2 As New Region(Me.ClientRectangle)
reg2.Exclude(reg1)
' Draw the string
Me.Graphics.Clip = reg1
Me.Graphics.DrawString(text, Me.Font, New SolidBrush(Me.OverLayColor), _
Me.DrawingRectangle, m_strFormat)
Me.Graphics.Clip = reg2
Me.Graphics.DrawString(text, Me.Font, New SolidBrush(Me.ForeColor), _
Me.DrawingRectangle, m_strFormat)
reg1.Dispose()
reg2.Dispose()
End Sub
ShowPercentage
函数以一种非常直接的方式使用此函数
Public Sub ShowPercentage()
Me.ShowText(Math.Round(Me.Percentage, _
Me.PercentageDecimals).ToString & "%")
End Sub
每次调整控件大小以及每次更改填充时,都使用以下代码确定要绘制的矩形
Private Sub setDrawingRectangle()
' Determine the coordinates and size of the drawing rectangle
' depending on the progress bar size and padding
Me.DrawingRectangle = New RectangleF(Me.Padding.Left, _
Me.Padding.Top, _
Me.Width - Me.Padding.Left - Me.Padding.Right, _
Me.Height - Me.Padding.Top - Me.Padding.Bottom)
End Sub
请注意,此属性用于每个绘制事件。另一个用于每个绘制事件的属性是 stringformat
。 每次更改对齐方式时,都会设置此属性。
Private Sub setStringFormat()
' Determine the horizontal alignment
Select Case Me.PercentageAlign
Case ContentAlignment.BottomCenter, _
ContentAlignment.BottomLeft, ContentAlignment.BottomRight
m_strFormat.LineAlignment = StringAlignment.Far
Case ContentAlignment.MiddleCenter, _
ContentAlignment.MiddleLeft, ContentAlignment.MiddleRight
m_strFormat.LineAlignment = StringAlignment.Center
Case ContentAlignment.TopCenter, _
ContentAlignment.TopLeft, ContentAlignment.TopRight
m_strFormat.LineAlignment = StringAlignment.Near
End Select
' Determine the vertical alignment
Select Case Me.PercentageAlign
Case ContentAlignment.BottomLeft, _
ContentAlignment.MiddleLeft, ContentAlignment.TopLeft
m_strFormat.Alignment = StringAlignment.Near
Case ContentAlignment.BottomCenter, _
ContentAlignment.MiddleCenter, ContentAlignment.TopCenter
m_strFormat.Alignment = StringAlignment.Center
Case ContentAlignment.BottomRight, _
ContentAlignment.MiddleRight, ContentAlignment.TopRight
m_strFormat.Alignment = StringAlignment.Far
End Select
End Sub
历史
1.0.10 版中的更改
- 添加了百分比格式属性,允许您使用自定义格式
- 修复了导致百分比无法正确显示的 XP 错误
- 为 SVN 功能创建了 SourceForge 项目
1.0.9 版中的更改
- 修复了一些释放问题(非常感谢 JohnH 帮助我解决这个问题!)
- 修复了使用多个小数时百分比计算中的错误
- 向演示添加了自动递增功能,并向一些条添加了小数
1.0.6 版中的更改
- 通过不为每个绘制事件重新计算某些值来提高组件效率
- 添加了多个新事件
1.0.5 版中的更改
- 添加了额外的文档和事件
1.0.4 版中的更改
- 修复了对齐错误
- 添加了填充属性