65.9K
CodeProject 正在变化。 阅读更多。
Home

带百分比的进度条

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.48/5 (21投票s)

2009年3月8日

GPL3

3分钟阅读

viewsIcon

183774

downloadIcon

11564

此组件扩展了原生的 .NET 进度条,增加了百分比属性,并可在进度条中显示百分比。

pbarWithPercentageDemo.gif pbarWithPercentageDemo.gif

引言

这个类扩展了原生的 .NET 进度条,增加了一个百分比属性,可以在进度条内部显示,用于获取或设置进度条本身的值。文本可以通过 Alignment 属性对齐,并且具有 FontPadding 属性以允许进一步的自定义。最重要的是,您可以更改进度条彩色部分中百分比的颜色。

你可能会问,为什么又有一个进度条控件?很简单。在创建此控件之前,我做了很多研究,希望能找到一个能够在进度条中显示百分比的控件。大多数控件都成功地实现了这一点,具有不同程度的自定义选项,并且在 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

progbarwithpercentage.gif

组件内部

现在它是如何实际工作的呢?我将尝试给您一个合理的理解。

最重要的函数是 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 版中的更改

  • 修复了对齐错误
  • 添加了填充属性
© . All rights reserved.