渐变色的进度条控件

发布于:2025-07-03 ⋅ 阅读:(23) ⋅ 点赞:(0)

近日,用VB.net2003重写了一个渐变色的进度条控件。主要有以下功能:

  1. 支持自定义进度条分段数量,可拆分为多个步骤;每个步骤可独立显示完成百分比及渐变色效果。

  2. 每个步骤均可配置任务名称和描述;运行时能实时显示当前执行步骤。

  3. 允许设置各分进度条的权重比例,系统会自动按比例调整各步骤的显示宽度。

  4. 可灵活调整各步骤的完成进度,并实时更新对应的渐变色显示。

完整实现细节请参考源代码,其中包含详尽的注释说明。分享给大家。

Public Class BqUProgressBar
    Inherits System.Windows.Forms.UserControl

#Region " Windows 窗体设计器生成的代码 "

    Public Sub New()
        MyBase.New()
        '该调用是 Windows 窗体设计器所必需的。
        InitializeComponent()
        '在 InitializeComponent() 调用之后添加任何初始化
        Call mIni() ' 初始化   20250628重新添加的
    End Sub

    'UserControl 重写 dispose 以清理组件列表。
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    'Windows 窗体设计器所必需的
    Private components As System.ComponentModel.IContainer

    '注意: 以下过程是 Windows 窗体设计器所必需的
    '可以使用 Windows 窗体设计器修改此过程。
    '不要使用代码编辑器修改它。
    Private WithEvents oGroupBox As System.Windows.Forms.GroupBox
    Private WithEvents oPanel As System.Windows.Forms.Panel
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Me.oGroupBox = New System.Windows.Forms.GroupBox
        Me.oPanel = New System.Windows.Forms.Panel
        Me.oGroupBox.SuspendLayout()
        Me.SuspendLayout()
        '
        'oGroupBox
        '
        Me.oGroupBox.Controls.Add(Me.oPanel)
        Me.oGroupBox.Dock = System.Windows.Forms.DockStyle.Fill
        Me.oGroupBox.Location = New System.Drawing.Point(0, 0)
        Me.oGroupBox.Name = "oGroupBox"
        Me.oGroupBox.Size = New System.Drawing.Size(400, 50)
        Me.oGroupBox.TabIndex = 0
        Me.oGroupBox.TabStop = False
        '
        'oPanel
        '
        Me.oPanel.Dock = System.Windows.Forms.DockStyle.Fill
        Me.oPanel.Location = New System.Drawing.Point(3, 21)
        Me.oPanel.Name = "oPanel"
        Me.oPanel.Size = New System.Drawing.Size(394, 26)
        Me.oPanel.TabIndex = 0
        '
        'BqUProgressBar
        '
        Me.Controls.Add(Me.oGroupBox)
        Me.Name = "BqUProgressBar"
        Me.Size = New System.Drawing.Size(400, 50)
        Me.oGroupBox.ResumeLayout(False)
        Me.ResumeLayout(False)

    End Sub

#End Region

    ' 初始化   20250628重新添加的
    Sub mIni()
        ''设置控件样式
        Me.SetStyle(System.Windows.Forms.ControlStyles.DoubleBuffer, True)   '在缓冲区绘制控件,再显示在屏幕上
        Me.SetStyle(System.Windows.Forms.ControlStyles.UserPaint, True)      '自行绘制控件
        Me.SetStyle(System.Windows.Forms.ControlStyles.AllPaintingInWmPaint, True)  '重绘时减少窗口闪烁
        Me.SetStyle(System.Windows.Forms.ControlStyles.ResizeRedraw, True)

        Me.SuspendLayout()   '临时挂起控件的布局逻辑
        '' 初始化默认值
        _lnProIndex = 0      '当前步骤
        _lnProCount = 3      '默认为3个步骤
        Call mSetDefaults()  '装入初值
        ''设置初始尺寸()
        Me.Size = New System.Drawing.Size(400, 50)
    End Sub


#Region "私有变量"

    '是否完成初始化,没有的话,在设置百分比值时,强制完成初始化
    Private _lynIni As Boolean = False

    ' 当前执行步骤索引
    Private _lnProIndex As Integer = 0
    ' 任务名称标签集合
    Private _loLblTagS As New ArrayList
    ' 百分比标签集合
    Private _loLblPerS As New ArrayList

    ' 进度条配置
    Private _lnProCount As Integer = 3    '分进度条数
    Private _lsProTagS() As String        '分进度条的标题,显示每个左边
    Private _lsProTitS() As String        '分进度条的内容,显示在分组的左上角  Title
    Private _lnProWeiS() As Single        '分进度条的宽度
    Private _lcProColor1S() As System.Drawing.Color  '起始色,用随机生成的颜色
    Private _lcProColor2S() As System.Drawing.Color  '结束色

    Private _lnProPerS() As Integer        '各进度条当前的数值

    ' 样式配置
    Private _ltDisplayMode As BqoTypeProMode = BqoTypeProMode.Both
    Private _lnCirRadiu As Integer = 15  '圆角半径

#End Region

#Region "公共枚举"
    '' 文本显示模式枚举
    Public Enum BqoTypeProMode
        None          ' 不显示文本
        Percentage    ' 仅显示百分比
        TaskName      ' 仅显示任务名
        Both          ' 显示任务名和百分比
    End Enum

#End Region

#Region "公共属性"
    <Browsable(False), Category("Bqss"), Description("cdbqss属性提示:设置分进度的数量")> _
    Public WriteOnly Property BqpProCount() As Integer
        Set(ByVal value As Integer)
            value = IIf(value < 1, 1, value) '不能小于1
            If value > 0 Then
                _lnProCount = value
                Call mSetDefaults()         '装入初值
            End If
        End Set
    End Property

    <Browsable(False), Category("Bqss"), Description("cdbqss属性提示:设置分进度的任务名称数组")> _
    Public WriteOnly Property BqpProTagS() As String()
        Set(ByVal value As String())
            If value Is Nothing Then Exit Property
            Dim n As Integer = Math.Min(value.Length, _lnProCount)
            For i As Integer = 0 To n - 1
                _lsProTagS(i) = value(i)
            Next
        End Set
    End Property

    <Browsable(False), Category("Bqss"), Description("cdbqss属性提示:设置分进度的内容提示数组")> _
    Public WriteOnly Property BqpProTitS() As String()
        Set(ByVal value As String())
            If value Is Nothing Then Exit Property
            Dim n As Integer = Math.Min(value.Length, _lnProCount)
            For i As Integer = 0 To n - 1
                _lsProTitS(i) = value(i)
            Next
        End Set
    End Property

    <Browsable(False), Category("Bqss"), Description("cdbqss属性提示:设置分进度的比例权重数组")> _
    Public WriteOnly Property BqpProWeiS() As Single()
        Set(ByVal value As Single())
            If value Is Nothing Then Exit Property
            Dim n As Integer = Math.Min(value.Length, _lnProCount)
            For i As Integer = 0 To n - 1
                _lnProWeiS(i) = value(i)
                Debug.Write(vbTab & value(i) & ",")
            Next
            Debug.Write(vbCrLf)
        End Set
    End Property

    <Browsable(False), Category("Bqss"), Description("cdbqss属性提示:圆角半径")> _
    Public WriteOnly Property BqpCornerRadius() As Integer
        Set(ByVal value As Integer)
            If value < 0 Then value = 0
            _lnCirRadiu = value
        End Set
    End Property

    <Browsable(False), Category("Bqss"), Description("cdbqss属性提示:文本显示模式")> _
    Public WriteOnly Property BqpDisplayMode() As BqoTypeProMode
        Set(ByVal value As BqoTypeProMode)
            _ltDisplayMode = value
            Call mLblsVisible()     '更新标签可见性
        End Set
    End Property

    <Browsable(False), Category("Bqss"), Description("cdbqss属性提示:设置或获取当前执行步骤索引")> _
    Public WriteOnly Property BqpIndex() As Integer
        Set(ByVal value As Integer)
            If value < 0 Then value = 0
            If value > _lnProCount Then value = _lnProCount - 1
            _lnProIndex = value - 1
            Call mLblsColor()     ' 更新标签颜色
            Call mLblTitle()      ' 更新标题信息标签
        End Set
    End Property

    <Browsable(False), Category("Bqss"), Description("cdbqss属性提示:设置或获取当前步骤的进度百分比值")> _
    Public WriteOnly Property BqpValuePro() As Integer
        Set(ByVal value As Integer)
            If _lynIni = False Then
                Call mProIni()         '强制初始化
            End If
            mSetValuePro(value)  '当前分进度的百分比 
        End Set
    End Property

#End Region

#Region "公共方法"
    '''' <summary>
    '''' 设置指定分进度的进度值,可以不改变当前步骤,直接修改其进度值
    '''' </summary>
    '''' <param name="segmentIndex">分进度索引</param>
    '''' <param name="value">进度值(0-100)</param>
    <Description("设置指定分进度的进度值")> _
    Public Sub BqpSetProgress(ByVal nIndex As Integer, ByVal value As Integer)
        If _lynIni = False Then
            Call mProIni() '强制初始化
        End If

        ''' 设置指定分进度的进度值
        If _lynIni = False Then Exit Sub '初始化结束才运行
        If nIndex < 0 Or nIndex > _lnProCount Then Exit Sub '
        If value < 0 Then value = 0
        If value > 100 Then value = 100
        _lnProPerS(nIndex - 1) = value
        If nIndex - 1 = _lnProIndex Then
            mLblPercent(_lnProIndex)
            oPanel.Invalidate()
        End If
    End Sub
#End Region


#Region "内部方法  "

    ''' 随机颜色生成
    Private Function mGetRandColor() As System.Drawing.Color
        Static rnd As New Random   '随机数
        Return System.Drawing.Color.FromArgb(rnd.Next(1, 250), rnd.Next(1, 255), rnd.Next(1, 250))
    End Function

    ''' 更新标题信息标签
    Private Sub mLblTitle()
        If _lnProCount < 1 Then Exit Sub
        If _lsProTitS Is Nothing Then Exit Sub
        oGroupBox.Text = String.Format("总{0}步/第{1}步: {2}", _
                        _lnProCount, _lnProIndex + 1, _lsProTitS(_lnProIndex))
    End Sub

    ' 初始化默认值
    Private Sub mSetDefaults()
        Dim n As Integer = _lnProCount

        _lnProIndex = 0    '重新设置分进度条个数后,当前索引设置为0
        _lynIni = False    '重新进行初始化

        ' 重新初始化数组
        ReDim _lsProTagS(n - 1)
        ReDim _lsProTitS(n - 1)
        ReDim _lnProWeiS(n - 1)
        ReDim _lnProPerS(n - 1)
        ReDim _lcProColor1S(n - 1)
        ReDim _lcProColor2S(n - 1)

        ' 设置默认值
        For i As Integer = 0 To n - 1
            _lsProTagS(i) = "步骤" & (i + 1)
            _lsProTitS(i) = "第" & (i + 1) & "步骤的描述提示"
            _lnProWeiS(i) = 1.0F / n
            _lnProPerS(i) = 0

            _lcProColor1S(i) = mGetRandColor()   '起始色,随机值
            _lcProColor2S(i) = mGetRandColor()   '随机值
            '_lcProColor2S(i) = System.Drawing.Color.FromArgb(CInt(_lcProColor1S(i).R / 2), _
            '                      CInt(_lcProColor1S(i).G / 1.5), _
            '                      CInt(_lcProColor1S(i).B / 1.2))
        Next
    End Sub

    ''' 设置分进度数量
    Private Sub mProIni()
        '把进度条数据确定后,再调用这个方法,初始化每个分进度条
        Call mLblsCreate()
        Me.ResumeLayout(False)  '恢复正常的布局逻辑
        _lynIni = True

        Call mLblsLocation()         '排列标签位置
        Call mLblsColor()   ' 更新标签颜色
        Call mLblsVisible()  '更新标签可见性
        Call mLblTitle()        '更新标题信息标签
    End Sub

    ''' 设置当前步骤的进度百分比值
    Private Sub mSetValuePro(ByVal value As Integer)
        If _lynIni = False Then Exit Sub '初始化结束才运行
        value = IIf(value < 0, 0, value)
        value = IIf(value > 100, 100, value)
        ' 直接设置进度值
        _lnProPerS(_lnProIndex) = value
        mLblPercent(_lnProIndex)
        oPanel.Invalidate()
    End Sub


    ''' 圆角路径生成
    Private Function mGetRound(ByVal lRect As System.Drawing.RectangleF, ByVal lRadius As Integer) As System.Drawing.Drawing2D.GraphicsPath
        ' lRect   是一个矩形区域
        ' lRadius 是传入的圆角半径
        If _lynIni = False Then Exit Function '初始化结束才运行

        Dim oLin As New System.Drawing.Drawing2D.GraphicsPath   '定义一段曲线
        Dim nDiameter As Integer = lRadius * 2   '直径

        If nDiameter > lRect.Width Then nDiameter = CInt(lRect.Width)
        If nDiameter > lRect.Height Then nDiameter = CInt(lRect.Height)

        '在当前图形的四角追加一个圆弧
        oLin.AddArc(lRect.X, lRect.Y, nDiameter, nDiameter, 180, 90)
        oLin.AddArc(lRect.Right - nDiameter, lRect.Y, nDiameter, nDiameter, 270, 90)
        oLin.AddArc(lRect.Right - nDiameter, lRect.Bottom - nDiameter, nDiameter, nDiameter, 0, 90)
        oLin.AddArc(lRect.X, lRect.Bottom - nDiameter, nDiameter, nDiameter, 90, 90)
        oLin.CloseFigure()
        Return oLin

    End Function


#End Region


#Region "标签管理"
    ''' 创建分段标签
    Private Sub mLblsCreate()
        ' 清除旧标签
        For Each lbl As System.Windows.Forms.Label In _loLblTagS
            oPanel.Controls.Remove(lbl)
        Next
        For Each lbl As System.Windows.Forms.Label In _loLblPerS
            oPanel.Controls.Remove(lbl)
        Next
        _loLblTagS.Clear()
        _loLblPerS.Clear()

        ' 创建新标签
        For i As Integer = 0 To _lnProCount - 1
            ' 任务名称标签
            Dim lblTask As New System.Windows.Forms.Label
            With lblTask
                .Text = _lsProTagS(i)
                .TextAlign = System.Drawing.ContentAlignment.MiddleLeft
                .AutoSize = True
                .BackColor = System.Drawing.Color.Transparent
            End With
            _loLblTagS.Add(lblTask)
            oPanel.Controls.Add(lblTask)
            ' 百分比标签
            Dim lblPerc As New System.Windows.Forms.Label
            With lblPerc
                .Text = "0%"
                .TextAlign = System.Drawing.ContentAlignment.MiddleCenter
                .AutoSize = True
                .BackColor = System.Drawing.Color.Transparent
            End With
            _loLblPerS.Add(lblPerc)
            oPanel.Controls.Add(lblPerc)
        Next

    End Sub

    ''' 排列标签位置
    Private Sub mLblsLocation()
        If _lynIni = False Then Exit Sub '初始化结束才运行
        If _lnProCount < 1 Then Exit Sub
        If _loLblTagS Is Nothing Then Exit Sub
        If _loLblPerS Is Nothing Then Exit Sub
        If _lnProWeiS Is Nothing Then Exit Sub

        Dim panelWidth As Integer = oPanel.Width - 10
        Dim panelHeigh As Integer = oPanel.Height

        Dim totalWeight As Single = 0
        For i As Integer = 0 To _lnProCount - 1
            totalWeight += _lnProWeiS(i)
        Next

        Dim xPos As Single = 5

        For i As Integer = 0 To _lnProCount - 1
            ' 计算当前分段宽度
            Dim segWidth As Single = panelWidth * (_lnProWeiS(i) / totalWeight)

            If i < _lnProCount AndAlso i < _loLblTagS.Count AndAlso i < _loLblPerS.Count Then
                Dim lblTask As System.Windows.Forms.Label = CType(_loLblTagS(i), System.Windows.Forms.Label)
                Dim lblPerc As System.Windows.Forms.Label = CType(_loLblPerS(i), System.Windows.Forms.Label)

                ' 任务名称标签放在左侧 ,控件边界设置为指定位置和大小
                lblTask.SetBounds(CInt(xPos), 0, CInt(segWidth * 0.5), panelHeigh)
                ' 百分比标签放在中间
                lblPerc.SetBounds(CInt(xPos + segWidth * 0.45), 3, CInt(segWidth * 0.4), panelHeigh)
            End If
            xPos += segWidth
        Next
    End Sub

    ''' 更新标签颜色
    Private Sub mLblsColor()
        If _lynIni = False Then Exit Sub '初始化结束才运行
        For i As Integer = 0 To _lnProCount - 1
            If i < _loLblTagS.Count AndAlso i < _loLblPerS.Count Then
                Dim lblTask As System.Windows.Forms.Label = CType(_loLblTagS(i), System.Windows.Forms.Label)
                Dim lblPerc As System.Windows.Forms.Label = CType(_loLblPerS(i), System.Windows.Forms.Label)
                Dim nColoRight As Single = mGetColorBrigh(_lcProColor1S(i))   '获取颜色亮度,使得标签字体颜色与渐变背景有区别
                lblPerc.ForeColor = System.Drawing.Color.Black   '黑色
                If i < _lnProIndex Then
                    lblTask.ForeColor = System.Drawing.Color.Blue   ' 已完成
                ElseIf i = _lnProIndex Then
                    lblTask.ForeColor = System.Drawing.Color.Green  ' 当前步骤
                Else
                    lblTask.ForeColor = System.Drawing.Color.Red    ' 未开始
                End If
            End If
        Next
    End Sub

    ''' 更新标签可见性
    Private Sub mLblsVisible()
        If _lynIni = False Then Exit Sub '初始化结束才运行
        For i As Integer = 0 To _lnProCount - 1
            If i < _loLblTagS.Count AndAlso i < _loLblPerS.Count Then
                Dim lblTask As System.Windows.Forms.Label = CType(_loLblTagS(i), System.Windows.Forms.Label)
                Dim lblPerc As System.Windows.Forms.Label = CType(_loLblPerS(i), System.Windows.Forms.Label)

                Select Case _ltDisplayMode
                    Case BqoTypeProMode.None
                        lblTask.Visible = False
                        lblPerc.Visible = False
                    Case BqoTypeProMode.Percentage
                        lblTask.Visible = False
                        lblPerc.Visible = True
                    Case BqoTypeProMode.TaskName
                        lblTask.Visible = True
                        lblPerc.Visible = False
                    Case BqoTypeProMode.Both
                        lblTask.Visible = True
                        lblPerc.Visible = True
                End Select
            End If
        Next
    End Sub

    ''' 更新百分比标签
    Private Sub mLblPercent(ByVal nIndex As Integer)
        If _lynIni = False Then Exit Sub '初始化结束才运行
        If nIndex < 0 Or nIndex > _loLblPerS.Count Then Exit Sub

        Dim lblPerc As System.Windows.Forms.Label = CType(_loLblPerS(nIndex), System.Windows.Forms.Label)
        Dim nColoRight As Single = mGetColorBrigh(_lcProColor1S(nIndex))
        lblPerc.Text = _lnProPerS(nIndex) & "%"
        ''以下的可暂时不需要
        If _lnProPerS(nIndex) > 45 Then
            lblPerc.ForeColor = System.Drawing.Color.White  '白色
        Else
            If nIndex < _lnProIndex Then
                lblPerc.ForeColor = System.Drawing.Color.Blue
            ElseIf nIndex = _lnProIndex Then
                lblPerc.ForeColor = System.Drawing.Color.Green
            Else
                lblPerc.ForeColor = System.Drawing.Color.Red
            End If
        End If
        'lblPerc.Invalidate()
        ''Debug.WriteLine("步骤:" & nIndex & vbTab & " 百分比:" & lblPerc.Text & vbTab & "  色度:" & nColoRight)
    End Sub

    '' 获取颜色亮度 (0-1)
    Private Function mGetColorBrigh(ByVal c As System.Drawing.Color) As Single
        Return (0.299 * c.R + 0.587 * c.G + 0.114 * c.B) / 255
    End Function

#End Region

#Region "绘制逻辑"

    '''' 面板大小改变事件
    Private Sub oPanel_Resize(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles oPanel.Resize
        If _lynIni = False Then Exit Sub '初始化结束才运行
        Call mLblsLocation()             '排列标签位置   
        oPanel.Invalidate()     ' 强制重绘面板(刷新进度条显示)
    End Sub

    '''' 重写整个控件的大小改变事件
    Protected Overrides Sub OnResize(ByVal e As System.EventArgs)
        ' 当用户控件大小改变时,调整内部GroupBox的大小
        With Me.oGroupBox        '必须改变oGroupBox 和oPanel的大小
            .Width = Me.Width    '设置oGroupBox 的宽度高度与用户控件相同
            .Height = Me.Height
            .Dock = System.Windows.Forms.DockStyle.Fill
        End With
        With Me.oPanel            '当用户控件大小改变时,调整内部Panel的大小
            .Width = Me.Width - 6
            .Height = Me.Height - 24
            .Dock = System.Windows.Forms.DockStyle.Fill '填充整个GroupBox
        End With
    End Sub

    ''' 面板重绘事件 (当Panel需要刷新时触发)
    Private Sub oPanel_Paint(ByVal sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles oPanel.Paint
        If _lynIni = False Then Exit Sub '初始化结束才运行
        ' 获取绘图表面对象
        Dim g As System.Drawing.Graphics = e.Graphics
        ' 设置抗锯齿模式(使图形边缘更平滑)
        g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias

        ' 绘制背景  创建背景刷(使用Panel的背景色)
        Dim backBrush As New System.Drawing.SolidBrush(Me.oPanel.BackColor)

        ' 填充整个Panel区域为背景色
        g.FillRectangle(backBrush, oPanel.ClientRectangle)

        ' 绘制边框
        ' 创建边框画笔(使用Panel的背景色,宽度为1像素)
        Dim borderPen As New System.Drawing.Pen(Me.oPanel.BackColor, 1)
        Try
            ' 检查是否设置了圆角半径
            If _lnCirRadiu > 0 Then
                ' 创建圆角矩形区域
                Dim borderRectF As New System.Drawing.RectangleF(0, 0, oPanel.Width, oPanel.Height)
                ' 生成圆角路径
                Dim borderPath As System.Drawing.Drawing2D.GraphicsPath = mGetRound(borderRectF, _lnCirRadiu)
                ' 绘制圆角边框
                g.DrawPath(borderPen, borderPath)
            Else
                ' 绘制直角边框(普通矩形)
                g.DrawRectangle(borderPen, 0, 0, oPanel.Width - 1, oPanel.Height - 1)
            End If
        Catch ex As Exception
            ' 忽略绘制过程中可能发生的错误
        Finally
            ' 确保释放画笔资源
            If Not borderPen Is Nothing Then borderPen.Dispose()
        End Try
        ' 绘制分段进度
        Call mDrawProS(g)
    End Sub

    ''' 绘制分段进度条
    Private Sub mDrawProS(ByVal g As System.Drawing.Graphics)
        If _lynIni = False Then Exit Sub '初始化结束才运行
        ' 计算总权重 (所有分段的权重之和)
        Dim totalWeight As Single = 0
        For i As Integer = 0 To _lnProCount - 1
            totalWeight += _lnProWeiS(i)
        Next

        ' 获取Panel的宽度和高度
        Dim panelWidth As Integer = oPanel.Width
        Dim panelHeigh As Integer = oPanel.Height

        ' 初始化起始位置(从左侧开始绘制)
        Dim xPos As Single = 0

        For i As Integer = 0 To _lnProCount - 1
            ' 计算当前分段的宽度(根据权重比例)
            Dim segWidth As Single = panelWidth * (_lnProWeiS(i) / totalWeight)

            ' 定义当前分段的矩形区域
            Dim segRect As New System.Drawing.RectangleF(xPos, 0, segWidth, panelHeigh)

            ' 计算当前进度条的宽度(根据完成百分比)
            Dim progressWidth As Single = segRect.Width * _lnProPerS(i) / 100

            ' 检查是否需要绘制进度条(进度>0)
            If progressWidth > 0 Then
                ' 定义进度条的实际显示区域
                Dim progressRect As New System.Drawing.RectangleF(segRect.X, segRect.Y, progressWidth, segRect.Height)
                ' 绘制单个进度条
                mDrawBar(g, progressRect, i)
            End If

            ' 移动到下一个分段的起始位置
            xPos += segWidth
        Next
    End Sub

    ''' 绘制进度条
    Private Sub mDrawBar(ByVal g As System.Drawing.Graphics, ByVal oRect As System.Drawing.RectangleF, ByVal nIndex As Integer)
        If _lynIni = False Then Exit Sub '初始化结束才运行

        ' 声明渐变画笔
        Dim progBrush As System.Drawing.Drawing2D.LinearGradientBrush = Nothing
        Try
            progBrush = New System.Drawing.Drawing2D.LinearGradientBrush(oRect, _
                           _lcProColor1S(nIndex), _lcProColor2S(nIndex), _
                           System.Drawing.Drawing2D.LinearGradientMode.Horizontal)

            ' 圆角处理 检查是否设置了圆角半径
            If _lnCirRadiu > 0 Then
                ' 生成圆角路径 
                Dim oLin As System.Drawing.Drawing2D.GraphicsPath = mGetRound(oRect, _lnCirRadiu)

                ' 使用渐变画笔填充圆角路径
                g.FillPath(progBrush, oLin)
            Else
                ' 使用渐变画笔填充矩形区域
                g.FillRectangle(progBrush, oRect)
            End If
        Catch ex As Exception
            ' 忽略绘制过程中可能发生的错误
        Finally
            ' 确保释放画笔资源
            If Not progBrush Is Nothing Then progBrush.Dispose()
        End Try
    End Sub

#End Region



End Class

以下是演示测试窗口。


Public Class Form1
    Inherits System.Windows.Forms.Form

#Region " Windows 窗体设计器生成的代码 "

    Public Sub New()
        MyBase.New()

        '该调用是 Windows 窗体设计器所必需的。
        InitializeComponent()

        '在 InitializeComponent() 调用之后添加任何初始化

    End Sub

    '窗体重写 dispose 以清理组件列表。
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    'Windows 窗体设计器所必需的
    Private components As System.ComponentModel.IContainer

    '注意: 以下过程是 Windows 窗体设计器所必需的
    '可以使用 Windows 窗体设计器修改此过程。
    '不要使用代码编辑器修改它。
    Friend WithEvents BqUProgressBar1 As aa.BqUProgressBar
    Friend WithEvents Button1 As System.Windows.Forms.Button
    Friend WithEvents NumericUpDown1 As System.Windows.Forms.NumericUpDown
    Friend WithEvents RadioButton1 As System.Windows.Forms.RadioButton
    Friend WithEvents RadioButton2 As System.Windows.Forms.RadioButton
    Friend WithEvents RadioButton3 As System.Windows.Forms.RadioButton
    Friend WithEvents RadioButton4 As System.Windows.Forms.RadioButton
    Friend WithEvents Label1 As System.Windows.Forms.Label
    Friend WithEvents Label2 As System.Windows.Forms.Label
    Friend WithEvents ListBox1 As System.Windows.Forms.ListBox
    Friend WithEvents ListBox2 As System.Windows.Forms.ListBox
    Friend WithEvents Label3 As System.Windows.Forms.Label
    Friend WithEvents Label4 As System.Windows.Forms.Label
    Friend WithEvents NumericUpDown2 As System.Windows.Forms.NumericUpDown
    Friend WithEvents Label5 As System.Windows.Forms.Label
    Friend WithEvents NumericUpDown3 As System.Windows.Forms.NumericUpDown
    Friend WithEvents Label7 As System.Windows.Forms.Label
    Friend WithEvents NumericUpDown5 As System.Windows.Forms.NumericUpDown
    Friend WithEvents GroupBox1 As System.Windows.Forms.GroupBox
    Friend WithEvents Label6 As System.Windows.Forms.Label
    Friend WithEvents ListBox3 As System.Windows.Forms.ListBox
    Friend WithEvents Button2 As System.Windows.Forms.Button
    Friend WithEvents Button3 As System.Windows.Forms.Button
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Me.BqUProgressBar1 = New aa.BqUProgressBar
        Me.Button1 = New System.Windows.Forms.Button
        Me.NumericUpDown1 = New System.Windows.Forms.NumericUpDown
        Me.RadioButton1 = New System.Windows.Forms.RadioButton
        Me.RadioButton2 = New System.Windows.Forms.RadioButton
        Me.RadioButton3 = New System.Windows.Forms.RadioButton
        Me.RadioButton4 = New System.Windows.Forms.RadioButton
        Me.Label1 = New System.Windows.Forms.Label
        Me.Label2 = New System.Windows.Forms.Label
        Me.ListBox1 = New System.Windows.Forms.ListBox
        Me.ListBox2 = New System.Windows.Forms.ListBox
        Me.Label3 = New System.Windows.Forms.Label
        Me.Label4 = New System.Windows.Forms.Label
        Me.NumericUpDown2 = New System.Windows.Forms.NumericUpDown
        Me.Label5 = New System.Windows.Forms.Label
        Me.NumericUpDown3 = New System.Windows.Forms.NumericUpDown
        Me.Label7 = New System.Windows.Forms.Label
        Me.NumericUpDown5 = New System.Windows.Forms.NumericUpDown
        Me.GroupBox1 = New System.Windows.Forms.GroupBox
        Me.Label6 = New System.Windows.Forms.Label
        Me.ListBox3 = New System.Windows.Forms.ListBox
        Me.Button2 = New System.Windows.Forms.Button
        Me.Button3 = New System.Windows.Forms.Button
        CType(Me.NumericUpDown1, System.ComponentModel.ISupportInitialize).BeginInit()
        CType(Me.NumericUpDown2, System.ComponentModel.ISupportInitialize).BeginInit()
        CType(Me.NumericUpDown3, System.ComponentModel.ISupportInitialize).BeginInit()
        CType(Me.NumericUpDown5, System.ComponentModel.ISupportInitialize).BeginInit()
        Me.GroupBox1.SuspendLayout()
        Me.SuspendLayout()
        '
        'BqUProgressBar1
        '
        Me.BqUProgressBar1.Anchor = CType(((System.Windows.Forms.AnchorStyles.Top Or System.Windows.Forms.AnchorStyles.Left) _
                    Or System.Windows.Forms.AnchorStyles.Right), System.Windows.Forms.AnchorStyles)
        Me.BqUProgressBar1.Location = New System.Drawing.Point(8, 24)
        Me.BqUProgressBar1.Name = "BqUProgressBar1"
        Me.BqUProgressBar1.Size = New System.Drawing.Size(792, 50)
        Me.BqUProgressBar1.TabIndex = 0
        '
        'Button1
        '
        Me.Button1.Location = New System.Drawing.Point(152, 424)
        Me.Button1.Name = "Button1"
        Me.Button1.Size = New System.Drawing.Size(160, 32)
        Me.Button1.TabIndex = 1
        Me.Button1.Text = "给标签赋值"
        '
        'NumericUpDown1
        '
        Me.NumericUpDown1.Font = New System.Drawing.Font("宋体", 13.8!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(134, Byte))
        Me.NumericUpDown1.Location = New System.Drawing.Point(480, 168)
        Me.NumericUpDown1.Maximum = New Decimal(New Integer() {10, 0, 0, 0})
        Me.NumericUpDown1.Name = "NumericUpDown1"
        Me.NumericUpDown1.Size = New System.Drawing.Size(64, 34)
        Me.NumericUpDown1.TabIndex = 3
        Me.NumericUpDown1.Value = New Decimal(New Integer() {9, 0, 0, 0})
        '
        'RadioButton1
        '
        Me.RadioButton1.Location = New System.Drawing.Point(8, 32)
        Me.RadioButton1.Name = "RadioButton1"
        Me.RadioButton1.Size = New System.Drawing.Size(152, 24)
        Me.RadioButton1.TabIndex = 4
        Me.RadioButton1.Text = "不显示文本"
        '
        'RadioButton2
        '
        Me.RadioButton2.Location = New System.Drawing.Point(8, 64)
        Me.RadioButton2.Name = "RadioButton2"
        Me.RadioButton2.Size = New System.Drawing.Size(152, 24)
        Me.RadioButton2.TabIndex = 5
        Me.RadioButton2.Text = "仅显示百分比"
        '
        'RadioButton3
        '
        Me.RadioButton3.Location = New System.Drawing.Point(8, 96)
        Me.RadioButton3.Name = "RadioButton3"
        Me.RadioButton3.Size = New System.Drawing.Size(152, 24)
        Me.RadioButton3.TabIndex = 6
        Me.RadioButton3.Text = "仅显示任务名"
        '
        'RadioButton4
        '
        Me.RadioButton4.Location = New System.Drawing.Point(8, 128)
        Me.RadioButton4.Name = "RadioButton4"
        Me.RadioButton4.Size = New System.Drawing.Size(152, 24)
        Me.RadioButton4.TabIndex = 7
        Me.RadioButton4.Text = "显示任务名和百分比"
        '
        'Label1
        '
        Me.Label1.Location = New System.Drawing.Point(32, 96)
        Me.Label1.Name = "Label1"
        Me.Label1.TabIndex = 10
        Me.Label1.Text = "步骤标题"
        '
        'Label2
        '
        Me.Label2.Location = New System.Drawing.Point(152, 96)
        Me.Label2.Name = "Label2"
        Me.Label2.TabIndex = 12
        Me.Label2.Text = "步骤内容"
        '
        'ListBox1
        '
        Me.ListBox1.ItemHeight = 15
        Me.ListBox1.Location = New System.Drawing.Point(24, 120)
        Me.ListBox1.Name = "ListBox1"
        Me.ListBox1.Size = New System.Drawing.Size(120, 154)
        Me.ListBox1.TabIndex = 13
        '
        'ListBox2
        '
        Me.ListBox2.ItemHeight = 15
        Me.ListBox2.Location = New System.Drawing.Point(152, 120)
        Me.ListBox2.Name = "ListBox2"
        Me.ListBox2.Size = New System.Drawing.Size(168, 154)
        Me.ListBox2.TabIndex = 14
        '
        'Label3
        '
        Me.Label3.AutoSize = True
        Me.Label3.Location = New System.Drawing.Point(408, 168)
        Me.Label3.Name = "Label3"
        Me.Label3.Size = New System.Drawing.Size(67, 21)
        Me.Label3.TabIndex = 15
        Me.Label3.Text = "步骤数量"
        '
        'Label4
        '
        Me.Label4.AutoSize = True
        Me.Label4.Location = New System.Drawing.Point(408, 208)
        Me.Label4.Name = "Label4"
        Me.Label4.Size = New System.Drawing.Size(67, 21)
        Me.Label4.TabIndex = 17
        Me.Label4.Text = "当前步骤"
        '
        'NumericUpDown2
        '
        Me.NumericUpDown2.Font = New System.Drawing.Font("宋体", 13.8!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(134, Byte))
        Me.NumericUpDown2.Location = New System.Drawing.Point(480, 208)
        Me.NumericUpDown2.Maximum = New Decimal(New Integer() {10, 0, 0, 0})
        Me.NumericUpDown2.Minimum = New Decimal(New Integer() {1, 0, 0, 0})
        Me.NumericUpDown2.Name = "NumericUpDown2"
        Me.NumericUpDown2.Size = New System.Drawing.Size(64, 34)
        Me.NumericUpDown2.TabIndex = 16
        Me.NumericUpDown2.Value = New Decimal(New Integer() {1, 0, 0, 0})
        '
        'Label5
        '
        Me.Label5.AutoSize = True
        Me.Label5.Location = New System.Drawing.Point(408, 256)
        Me.Label5.Name = "Label5"
        Me.Label5.Size = New System.Drawing.Size(67, 21)
        Me.Label5.TabIndex = 19
        Me.Label5.Text = "百分比值"
        '
        'NumericUpDown3
        '
        Me.NumericUpDown3.Font = New System.Drawing.Font("宋体", 13.8!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(134, Byte))
        Me.NumericUpDown3.Location = New System.Drawing.Point(480, 248)
        Me.NumericUpDown3.Name = "NumericUpDown3"
        Me.NumericUpDown3.Size = New System.Drawing.Size(64, 34)
        Me.NumericUpDown3.TabIndex = 18
        Me.NumericUpDown3.Value = New Decimal(New Integer() {30, 0, 0, 0})
        '
        'Label7
        '
        Me.Label7.AutoSize = True
        Me.Label7.Location = New System.Drawing.Point(408, 120)
        Me.Label7.Name = "Label7"
        Me.Label7.Size = New System.Drawing.Size(67, 21)
        Me.Label7.TabIndex = 24
        Me.Label7.Text = "圆角半径"
        '
        'NumericUpDown5
        '
        Me.NumericUpDown5.Font = New System.Drawing.Font("宋体", 13.8!, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, CType(134, Byte))
        Me.NumericUpDown5.Location = New System.Drawing.Point(480, 120)
        Me.NumericUpDown5.Minimum = New Decimal(New Integer() {1, 0, 0, 0})
        Me.NumericUpDown5.Name = "NumericUpDown5"
        Me.NumericUpDown5.Size = New System.Drawing.Size(64, 34)
        Me.NumericUpDown5.TabIndex = 23
        Me.NumericUpDown5.Value = New Decimal(New Integer() {3, 0, 0, 0})
        '
        'GroupBox1
        '
        Me.GroupBox1.Controls.Add(Me.RadioButton4)
        Me.GroupBox1.Controls.Add(Me.RadioButton3)
        Me.GroupBox1.Controls.Add(Me.RadioButton2)
        Me.GroupBox1.Controls.Add(Me.RadioButton1)
        Me.GroupBox1.Location = New System.Drawing.Point(584, 120)
        Me.GroupBox1.Name = "GroupBox1"
        Me.GroupBox1.Size = New System.Drawing.Size(168, 160)
        Me.GroupBox1.TabIndex = 25
        Me.GroupBox1.TabStop = False
        Me.GroupBox1.Text = "显示样式"
        '
        'Label6
        '
        Me.Label6.AutoSize = True
        Me.Label6.Location = New System.Drawing.Point(64, 304)
        Me.Label6.Name = "Label6"
        Me.Label6.Size = New System.Drawing.Size(83, 21)
        Me.Label6.TabIndex = 27
        Me.Label6.Text = "各步骤比例"
        '
        'ListBox3
        '
        Me.ListBox3.ItemHeight = 15
        Me.ListBox3.Location = New System.Drawing.Point(152, 296)
        Me.ListBox3.Name = "ListBox3"
        Me.ListBox3.Size = New System.Drawing.Size(168, 109)
        Me.ListBox3.TabIndex = 28
        '
        'Button2
        '
        Me.Button2.Location = New System.Drawing.Point(40, 336)
        Me.Button2.Name = "Button2"
        Me.Button2.Size = New System.Drawing.Size(104, 32)
        Me.Button2.TabIndex = 29
        Me.Button2.Text = "产生随机数"
        '
        'Button3
        '
        Me.Button3.Location = New System.Drawing.Point(464, 312)
        Me.Button3.Name = "Button3"
        Me.Button3.Size = New System.Drawing.Size(208, 32)
        Me.Button3.TabIndex = 30
        Me.Button3.Text = "直接修改当前步骤的进度"
        '
        'Form1
        '
        Me.AutoScaleBaseSize = New System.Drawing.Size(8, 18)
        Me.ClientSize = New System.Drawing.Size(806, 497)
        Me.Controls.Add(Me.Button3)
        Me.Controls.Add(Me.Button2)
        Me.Controls.Add(Me.ListBox3)
        Me.Controls.Add(Me.Label6)
        Me.Controls.Add(Me.Label7)
        Me.Controls.Add(Me.Label5)
        Me.Controls.Add(Me.Label4)
        Me.Controls.Add(Me.Label3)
        Me.Controls.Add(Me.GroupBox1)
        Me.Controls.Add(Me.NumericUpDown5)
        Me.Controls.Add(Me.NumericUpDown3)
        Me.Controls.Add(Me.NumericUpDown2)
        Me.Controls.Add(Me.ListBox2)
        Me.Controls.Add(Me.ListBox1)
        Me.Controls.Add(Me.Label2)
        Me.Controls.Add(Me.Label1)
        Me.Controls.Add(Me.NumericUpDown1)
        Me.Controls.Add(Me.Button1)
        Me.Controls.Add(Me.BqUProgressBar1)
        Me.Name = "Form1"
        Me.Text = "Form1"
        CType(Me.NumericUpDown1, System.ComponentModel.ISupportInitialize).EndInit()
        CType(Me.NumericUpDown2, System.ComponentModel.ISupportInitialize).EndInit()
        CType(Me.NumericUpDown3, System.ComponentModel.ISupportInitialize).EndInit()
        CType(Me.NumericUpDown5, System.ComponentModel.ISupportInitialize).EndInit()
        Me.GroupBox1.ResumeLayout(False)
        Me.ResumeLayout(False)

    End Sub

#End Region

    Dim lyn As Boolean = False  '初始化是否结束
    Dim m1(10), m2(10) As String
    Dim m3(10) As Single


    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Call mIni()
        lyn = True
    End Sub
    Sub mIni()
        For i As Integer = 0 To 10
            m1(i) = String.Format("第 {0} 步  ", (i + 1))
            m2(i) = String.Format("第 {0} 步的内容提示", (i + 1))
        Next
        For i As Integer = 0 To 10
            m3(i) = Int(Rnd() * 300 + 1)
        Next
        Me.ListBox1.DataSource = m1
        Me.ListBox2.DataSource = m2
        Me.ListBox3.DataSource = m3
        Me.ListBox1.Invalidate()
        Me.ListBox2.Invalidate()
        Me.ListBox3.Invalidate()
        'Me.NumericUpDown1.Value = 10
    End Sub

    '当前步骤不能超过步骤数
    Private Sub NumericUpDown1_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NumericUpDown1.ValueChanged
        If lyn = False Then Exit Sub '初始化结束才运行
        Me.NumericUpDown2.Maximum = Me.NumericUpDown1.Value
        With Me.BqUProgressBar1

            .BqpProCount = NumericUpDown1.Value
        End With
    End Sub
    '当前步骤
    Private Sub NumericUpDown2_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NumericUpDown2.ValueChanged
        If lyn = False Then Exit Sub '初始化结束才运行
        With Me.BqUProgressBar1
            .BqpIndex = Me.NumericUpDown2.Value
        End With
    End Sub
    '当前步骤的百分比值
    Private Sub NumericUpDown3_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NumericUpDown3.ValueChanged
        If lyn = False Then Exit Sub '初始化结束才运行
        With Me.BqUProgressBar1
            .BqpValuePro = Me.NumericUpDown3.Value
        End With
    End Sub
    '圆角半径
    Private Sub NumericUpDown5_ValueChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NumericUpDown5.ValueChanged
        Me.BqUProgressBar1.BqpCornerRadius = Me.NumericUpDown5.Value
    End Sub
    '样式
    Private Sub RadioButton1_CheckedChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles RadioButton1.CheckedChanged, RadioButton2.CheckedChanged, RadioButton3.CheckedChanged, RadioButton4.CheckedChanged
        If Me.RadioButton1.Checked Then
            Me.BqUProgressBar1.BqpDisplayMode = BqUProgressBar.BqoTypeProMode.None
        ElseIf Me.RadioButton2.Checked Then
            Me.BqUProgressBar1.BqpDisplayMode = BqUProgressBar.BqoTypeProMode.Percentage
        ElseIf Me.RadioButton3.Checked Then
            Me.BqUProgressBar1.BqpDisplayMode = BqUProgressBar.BqoTypeProMode.TaskName
        Else
            Me.BqUProgressBar1.BqpDisplayMode = BqUProgressBar.BqoTypeProMode.Both
        End If
    End Sub

    '装入新值
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        With Me.BqUProgressBar1
            .BqpProTagS = m1
            .BqpProTitS = m2
            .BqpProWeiS = m3
        End With
    End Sub
    '产生随机数
    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        ReDim m3(11)
        Me.ListBox3.DataSource = Nothing
        For i As Integer = 0 To 10
            m3(i) = Int(Rnd() * 300 + 1)
        Next
        Me.ListBox3.DataSource = m3
        Me.ListBox3.Refresh()
    End Sub

    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
        Dim n1 As Integer = Me.NumericUpDown3.Value   '目前的比例
        Dim n2 As Integer = Me.NumericUpDown2.Value    '当前步骤
        For i As Integer = 1 To n1
            Me.BqUProgressBar1.BqpSetProgress(n2, i)
        Next
    End Sub

    
End Class

测试窗口直接使用系统控件,并采用默认的控件名称,简单易懂。


网站公告

今日签到

点亮在社区的每一天
去签到