How-to 做一個自己的"進度列(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

留言

匿名表示…
有點難懂 ,剛學美化 ,能給我原碼嗎 ? 丟個載點 謝謝你
bauann寫道…
Hi, 原始碼是VS2008的,在下面的位置
http://bauann-makeit.blogspot.tw/2009/01/how-to-progressbar.html
你在玩玩看吧 :)
bauann寫道…
連結貼錯了 Orz
https://dl.dropboxusercontent.com/u/22475700/progessBar.zip
dropbox這個才對

這個網誌中的熱門文章

開啟cshtml檔案時,出現『並未將物件參考設定為物件執行個體』的錯誤訊息

無法設定中斷點 尚未載入符號檔

DataGridView欄位計算總合