目的:實現如下圖所示效果:
寫實現進度條的類,繼承DataGridViewTextBoxColumn類,代碼如下:
Imports System
Imports System.Drawing
Imports System.Windows.Forms
Public Class DataGridViewPrassBar
Public Class DataGridViewProgressBarColumn
Inherits DataGridViewTextBoxColumn
Public Sub New()
Me.CellTemplate = New DataGridViewProgressBarCell()
End Sub
Public Overrides Property CellTemplate() As DataGridViewCell
Get
Return MyBase.CellTemplate
End Get
Set(ByVal value As DataGridViewCell)
If Not TypeOf value Is DataGridViewProgressBarCell Then
Throw New InvalidCastException("請指定DataGridViewProgressBarCell")
End If
MyBase.CellTemplate = value
End Set
End Property
Public Property Maximum() As Integer
Get
Return CType(Me.CellTemplate, DataGridViewProgressBarCell).Maximum
End Get
Set(ByVal value As Integer)
If Me.Maximum = value Then
Return
End If
CType(Me.CellTemplate, DataGridViewProgressBarCell).Maximum = value
If Me.DataGridView Is Nothing Then
Return
End If
Dim rowCount As Integer = Me.DataGridView.RowCount
Dim i As Integer
For i = 0 To rowCount - 1
Dim r As DataGridViewRow = Me.DataGridView.Rows.SharedRow(i)
CType(r.Cells(Me.Index), DataGridViewProgressBarCell).Maximum = value
Next i
End Set
End Property
Public Property Mimimum() As Integer
Get
Return CType(Me.CellTemplate, DataGridViewProgressBarCell).Mimimum
End Get
Set(ByVal value As Integer)
If Me.Mimimum = value Then
Return
End If
CType(Me.CellTemplate, DataGridViewProgressBarCell).Mimimum = value
If Me.DataGridView Is Nothing Then
Return
End If
Dim rowCount As Integer = Me.DataGridView.RowCount
Dim i As Integer
For i = 0 To rowCount - 1
Dim r As DataGridViewRow = Me.DataGridView.Rows.SharedRow(i)
CType(r.Cells(Me.Index), DataGridViewProgressBarCell).Mimimum = value
Next i
End Set
End Property
End Class
Public Class DataGridViewProgressBarCell
Inherits DataGridViewTextBoxCell
Public Sub New()
Me.maximumValue = 100
Me.mimimumValue = 0
End Sub
Private maximumValue As Integer
Public Property Maximum() As Integer
Get
Return Me.maximumValue
End Get
Set(ByVal value As Integer)
Me.maximumValue = value
End Set
End Property
Private mimimumValue As Integer
Public Property Mimimum() As Integer
Get
Return Me.mimimumValue
End Get
Set(ByVal value As Integer)
Me.mimimumValue = value
End Set
End Property
Public Overrides ReadOnly Property ValueType() As Type
Get
Return GetType(Integer)
End Get
End Property
Public Overrides ReadOnly Property DefaultNewRowValue() As Object
Get
Return 0
End Get
End Property
Public Overrides Function Clone() As Object
Dim cell As DataGridViewProgressBarCell = CType(MyBase.Clone(), DataGridViewProgressBarCell)
cell.Maximum = Me.Maximum
cell.Mimimum = Me.Mimimum
Return cell
End Function
Protected Overrides Sub Paint(ByVal graphics As Graphics, ByVal clipBounds As Rectangle, ByVal cellBounds As Rectangle, ByVal rowIndex As Integer, ByVal cellState As DataGridViewElementStates, ByVal value As Object, ByVal formattedValue As Object, ByVal errorText As String, ByVal cellStyle As DataGridViewCellStyle, ByVal advancedBorderStyle As DataGridViewAdvancedBorderStyle, ByVal paintParts As DataGridViewPaintParts)
Dim intValue As Integer = 0
If TypeOf value Is Integer Then
intValue = CInt(value)
End If
If intValue < Me.mimimumValue Then
intValue = Me.mimimumValue
End If
If intValue > Me.maximumValue Then
intValue = Me.maximumValue
End If
Dim rate As Double = CDbl(intValue - Me.mimimumValue) / (Me.maximumValue - Me.mimimumValue)
If (paintParts And DataGridViewPaintParts.Border) = DataGridViewPaintParts.Border Then
Me.PaintBorder(graphics, clipBounds, cellBounds, cellStyle, advancedBorderStyle)
End If
Dim borderRect As Rectangle = Me.BorderWidths(advancedBorderStyle)
Dim paintRect As New Rectangle(cellBounds.Left + borderRect.Left, cellBounds.Top + borderRect.Top, cellBounds.Width - borderRect.Right, cellBounds.Height - borderRect.Bottom)
Dim isSelected As Boolean = ((cellState And DataGridViewElementStates.Selected) = DataGridViewElementStates.Selected)
Dim bkColor As Color
If isSelected AndAlso (paintParts And DataGridViewPaintParts.SelectionBackground) = DataGridViewPaintParts.SelectionBackground Then
bkColor = cellStyle.SelectionBackColor
Else
bkColor = cellStyle.BackColor
End If
If (paintParts And DataGridViewPaintParts.Background) = DataGridViewPaintParts.Background Then
Dim backBrush As New SolidBrush(bkColor)
Try
graphics.FillRectangle(backBrush, paintRect)
Finally
backBrush.Dispose()
End Try
End If
paintRect.Offset(cellStyle.Padding.Right, cellStyle.Padding.Top)
paintRect.Width -= cellStyle.Padding.Horizontal
paintRect.Height -= cellStyle.Padding.Vertical
If (paintParts And DataGridViewPaintParts.ContentForeground) = DataGridViewPaintParts.ContentForeground Then
If ProgressBarRenderer.IsSupported Then
ProgressBarRenderer.DrawHorizontalBar(graphics, paintRect)
Dim barBounds As New Rectangle(paintRect.Left + 3, paintRect.Top + 3, paintRect.Width - 4, paintRect.Height - 6)
barBounds.Width = CInt(Math.Round((barBounds.Width * rate)))
ProgressBarRenderer.DrawHorizontalChunks(graphics, barBounds)
Else
graphics.FillRectangle(Brushes.White, paintRect)
graphics.DrawRectangle(Pens.Black, paintRect)
Dim barBounds As New Rectangle(paintRect.Left + 1, paintRect.Top + 1, paintRect.Width - 1, paintRect.Height - 1)
barBounds.Width = CInt(Math.Round((barBounds.Width * rate)))
graphics.FillRectangle(Brushes.Blue, barBounds)
End If
End If
If Me.DataGridView.CurrentCellAddress.X = Me.ColumnIndex AndAlso Me.DataGridView.CurrentCellAddress.Y = Me.RowIndex AndAlso (paintParts And DataGridViewPaintParts.Focus) = DataGridViewPaintParts.Focus AndAlso Me.DataGridView.Focused Then
Dim focusRect As Rectangle = paintRect
focusRect.Inflate(-3, -3)
ControlPaint.DrawFocusRectangle(graphics, focusRect)
End If
If (paintParts And DataGridViewPaintParts.ContentForeground) = DataGridViewPaintParts.ContentForeground Then
Dim txt As String = String.Format("{0}%", Math.Round((rate * 100)))
Dim flags As TextFormatFlags = TextFormatFlags.HorizontalCenter Or TextFormatFlags.VerticalCenter
Dim fColor As Color = cellStyle.ForeColor
paintRect.Inflate(-2, -2)
TextRenderer.DrawText(graphics, txt, cellStyle.Font, paintRect, fColor, flags)
End If
If (paintParts And DataGridViewPaintParts.ErrorIcon) = DataGridViewPaintParts.ErrorIcon AndAlso Me.DataGridView.ShowCellErrors AndAlso Not String.IsNullOrEmpty(errorText) Then
Dim iconBounds As Rectangle = Me.GetErrorIconBounds(graphics, cellStyle, rowIndex)
iconBounds.Offset(cellBounds.X, cellBounds.Y)
Me.PaintErrorIcon(graphics, iconBounds, cellBounds, errorText)
End If
End Sub
End Class
End Class
運行項目進行編譯
對DataGridView進行列編輯,選中要設置進度條顯示的列,把columnType設置爲自己寫的DataGridViewProgressBarColumn,默認的是DataGridViewTextBoxColumn屬性。可以定義好最大值和最小值,默認的是0,100.把value值賦值成介於最大值和最小值之間的整數就可以顯示進度條的效果了。
如果不正常顯示的話,檢查是不是正整數值,另外不要把賦值符號“=”右邊的值寫成計算的形式,要把計算好的值直接賦予value值。