在开发应用程序时,经常需要向用户展示任务的进度。进度条控件是实现这一功能的标准组件。然而,标准的进度条控件可能无法满足所有需求,特别是在需要高度定制化界面时。本文将介绍如何在.NET Framework4.0环境下使用Visual Studio开发一个可自定义的进度条控件。
首先,需要在Visual Studio中创建一个新的类库项目。右键点击解决方案资源管理器中的项目名称,选择“添加引用”,然后从.NET选项卡中添加以下引用:
接下来,需要导入一些必要的命名空间:
Imports System
Imports System.Drawing
Imports System.Drawing.Drawing2D
Imports System.Windows.Forms
定义一个继承自Control的进度条类,并添加一些基本的变量和属性:
Public Class Progress_bar
Inherits Control
' 定义一些基本的变量
Private min As Integer = 0
Private max As Integer = 100
Private val As Integer = 0
Public usegrad As Boolean = False
Public bkColor As Color = Color.Transparent
Public enBackColor As Boolean = False
Public BarColor As Color = Color.Blue
Public gradcolor1 As Color = Color.DeepSkyBlue
Public gradcolor2 As Color = Color.Blue
Dim HColor As Color = Color.WhiteSmoke
Dim hStyle As HatchStyle
Dim drawhBrush As Boolean = False
Dim hatchBackColor As Color = Color.Transparent
Public drwLabel As Boolean = False
Public draw3D As Boolean = False
定义构造函数,并重写OnCreateControl方法。同时,定义一些属性,如Minimum、Maximum和Value等:
Public Sub New()
MyBase.New()
SetStyle(ControlStyles.SupportsTransparentBackColor, True)
End Sub
Protected Overrides Sub OnCreateControl()
MyBase.OnCreateControl()
End Sub
Public Property Minimum() As Integer
Get
Return min
End Get
Set(ByVal Value As Integer)
If Value < 0 Then min = 0
If Value > max Then min = Value
If Value < min Then val = min
Me.Invalidate()
End Set
End Property
Public Property Maximum() As Integer
Get
Return max
End Get
Set(ByVal Value As Integer)
If Value < min Then min = Value
max = Value
If (val > max) Then val = max
Me.Invalidate()
End Set
End Property
Public Property Value As Integer
Get
Return val
End Get
Set(ByVal Value As Integer)
Dim oldvalue As Integer = val
If Value < min Then val = min
ElseIf Value > max Then val = max
Else val = Value
End If
Dim newValueRect As Rectangle = Me.ClientRectangle
Dim oldValueRect As Rectangle = Me.ClientRectangle
Dim percent As Decimal
percent = (val - min) / (max - min)
newValueRect.Width = newValueRect.Width * percent
percent = (oldvalue - min) / (max - min)
oldValueRect.Width = oldValueRect.Width * percent
Dim updateRect As Rectangle = New Rectangle()
If newValueRect.Width > oldValueRect.Width Then
updateRect.X = oldValueRect.Size.Width
updateRect.Width = newValueRect.Width - oldValueRect.Width
Else
updateRect.X = newValueRect.Size.Width
updateRect.Width = oldValueRect.Width - newValueRect.Width
End If
updateRect.Height = Me.Height
Me.Invalidate(updateRect.X)
End Set
End Property
重写OnPaint方法,根据进度值绘制进度条:
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
MyBase.OnPaint(e)
Dim g As Graphics = e.Graphics
Dim brush As SolidBrush = New SolidBrush(BarColor)
Dim bkbrush As New SolidBrush(MyBase.BackColor)
Dim hbrush As New HatchBrush(hStyle, HColor, Color.Transparent)
Dim gbrush As LinearGradientBrush = New LinearGradientBrush(Me.ClientRectangle, Color.FromArgb(255, gradcolor1), Color.FromArgb(255, gradcolor2), LinearGradientMode.Vertical)
Dim percent As Decimal = (val - min) / (max - min)
Dim cliRect As Rectangle = New Rectangle(0, 0, Me.ClientRectangle.Width, Me.ClientRectangle.Height)
Dim rect As Rectangle = New Rectangle(1, 1, Me.ClientRectangle.Width - 2, Me.ClientRectangle.Height - 2)
rect.Width = rect.Width * percent
g.SmoothingMode = SmoothingMode.AntiAlias
g.CompositingQuality = CompositingQuality.AssumeLinear
If usegrad = True Then
g.FillRectangle(bkbrush, cliRect)
g.FillRectangle(gbrush, rect)
ElseIf drawhBrush = True Then
g.FillRectangle(hbrush, rect)
Else
g.FillRectangle(bkbrush, cliRect)
g.FillRectangle(brush, rect)
End If
If draw3D = True Then
Draw_3D_Border(g)
End If
If drwLabel = True Then
Dim str As String = CType(val & "%", String)
Dim mybrush As New SolidBrush(Me.ForeColor)
g.DrawString(str, Me.Font, mybrush, New Point((Me.ClientRectangle.Width / 2) - str.Length * 4, (Me.ClientRectangle.Height / 2) - (FontHeight / 2)))
End If
brush.Dispose()
bkbrush.Dispose()
hbrush.Dispose()
gbrush.Dispose()
g.Dispose()
End Sub
Private Sub Draw_3D_Border(ByVal g As Graphics)
Dim penWidth As Integer = Pens.White.Width
g.DrawLine(Pens.DarkGray, New Point(Me.ClientRectangle.Left, Me.ClientRectangle.Top), New Point(Me.ClientRectangle.Width - penWidth, Me.ClientRectangle.Top))
g.DrawLine(Pens.DarkGray, New Point(Me.ClientRectangle.Left, Me.ClientRectangle.Top), New Point(Me.ClientRectangle.Left, Me.ClientRectangle.Height - penWidth))
g.DrawLine(Pens.White, New Point(Me.ClientRectangle.Left, Me.ClientRectangle.Height - penWidth), New Point(Me.ClientRectangle.Width - penWidth, Me.ClientRectangle.Height - penWidth))
g.DrawLine(Pens.White, New Point(Me.ClientRectangle.Width - penWidth, Me.ClientRectangle.Top), New Point(Me.ClientRectangle.Width - penWidth, Me.ClientRectangle.Height - penWidth))
End Sub