How-to 做一個自己的"進度列(ProgressBar)"

今天剛好同事問我有關ProgressBar的問題,需求是因為他是利用ProgressBar在需要長時間動作時讓使用者知道程式是沒有當掉的,但是遇到同步動作的時候連ProgressBar也會有停頓的情形,所以想要用多執行緒來實做看看;下面這邊是一個簡單的實做範例,可以參考看看

今天剛好同事問我有關ProgressBar的問題,需求是因為他是利用ProgressBar在需要長時間動作時讓使用者知道程式是沒有當掉的,但是遇到同步動作的時候連ProgressBar也會有停頓的情形,所以想要用多執行緒來實做看看;下面這邊是一個簡單的實做範例,可以參考看看 下面這張圖是實際拉到Form上面時的效果

 

再來是元件的程式碼,名稱我是亂取,叫做MyLabel,還沒有經過詳細的測試,有問題的話請讓我知道吧~ orz


Imports System.Threading

Public Class myLabel
    Inherits Control

    Private _thdDraw As Thread
    Private _gr As Graphics
    Private _myBrush As New SolidBrush(MyBase.ForeColor)
    'Private _myB As New System.Drawing.Drawing2D.LinearGradientBrush( 
    Private _Progess As Integer = 0
    Private _Max As Integer = 100
    Private _Min As Integer = 0
    Private _AutoDrawInterval As Integer = 1000
    Private _bolStop As Boolean = False
    Private _bolEnable As Boolean = False

    Private _stringFormat As New StringFormat
    Private _bsText As New SolidBrush(Color.Black)

    ''' 
    ''' 複寫掉設定ForeColor時的動作
    ''' 
    ''' 
    ''' 
    ''' 
    Public Overrides Property ForeColor() As System.Drawing.Color
        Get
            Return MyBase.ForeColor
        End Get
        Set(ByVal value As System.Drawing.Color)
            MyBase.ForeColor = value
            _myBrush = New SolidBrush(value)
            Draw()
        End Set
    End Property

    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        Draw()
        MyBase.OnPaint(e)
    End Sub

    ''' 
    ''' 目前進度
    ''' 
    ''' 
    ''' 
    ''' 
    Public Property Progess() As Integer
        Get
            Return _Progess
        End Get
        Set(ByVal value As Integer)
            _Progess = value
            Draw()
        End Set
    End Property

    ''' 
    ''' 自動重繪間隔時間
    ''' 
    ''' 
    ''' 
    ''' 
    Public Property AutoDrawInterval() As Integer
        Get
            Return _AutoDrawInterval
        End Get
        Set(ByVal value As Integer)
            _AutoDrawInterval = value
        End Set
    End Property

    ''' 
    ''' 啟動自動重繪
    ''' 
    ''' 
    ''' 
    ''' 
    Public Property EnableAutoDraw() As Boolean
        Get
            Return _bolEnable
        End Get
        Set(ByVal value As Boolean)
            If value Then
                _stringFormat.LineAlignment = StringAlignment.Center
                _stringFormat.Alignment = StringAlignment.Center
                _bolEnable = True
                _bolStop = False
                If _thdDraw Is Nothing Then
                    _thdDraw = New Thread(AddressOf AutoDraw)
                    _thdDraw.Start()
                Else
                    If _thdDraw.ThreadState <> ThreadState.Running Then
                        _thdDraw.Start()
                    End If
                End If
            Else
                _bolEnable = False
                _bolStop = True
                Try
                    If _thdDraw.ThreadState <> ThreadState.Stopped Then
                        _thdDraw.Abort()
                    End If
                Catch ex As Exception
                    ''
                End Try
                _thdDraw = Nothing
            End If
        End Set
    End Property

    Private Sub Draw()
        MyBase.SuspendLayout()
        _gr = Me.CreateGraphics
        _gr.Clear(MyBase.BackColor)
        _gr.DrawRectangle(New Pen(_myBrush), 0, 0, MyBase.Width - 1, MyBase.Height - 1)
        _gr.FillRectangle(_myBrush, 0, 0, CInt(MyBase.Width * (_Progess / _Max)), MyBase.Height)
        MyBase.ResumeLayout()
    End Sub

    ''' 
    ''' 多執行緒繪製
    ''' 
    ''' 
    Private Sub AutoDraw()
        Do While Not _bolStop
            If _Progess >= _Max Then
                _Progess = _Min
            Else
                _Progess += 1
            End If
            MyBase.SuspendLayout()
            _gr = Me.CreateGraphics
            _gr.Clear(MyBase.BackColor)
            _gr.DrawRectangle(New Pen(_myBrush), 0, 0, MyBase.Width - 1, MyBase.Height - 1)
            _gr.FillRectangle(_myBrush, 0, 0, CInt(MyBase.Width * (_Progess / _Max)), MyBase.Height)
            _gr.DrawString(CInt((_Progess / _Max) * 100) & "%", _
                           MyBase.Font, _bsText, New RectangleF(0, 0, 50, MyBase.Height), _stringFormat)
            '_gr.DrawString("Please wait...", _
            '               MyBase.Font, _bsText, New RectangleF(0, 0, 100, MyBase.Height), _stringFormat)
            MyBase.ResumeLayout()
            Thread.Sleep(_AutoDrawInterval)
        Loop
    End Sub
End Class

叫用的範例


MyLabel1.ForeColor = Color.LightPink
        MyLabel1.AutoDrawInterval = 50
        MyLabel1.EnableAutoDraw = True