在DataGridView中绘制进度条

VB.NET中,经常需要在DataGridView中展示数据的进度或百分比,以便用户可以直观地比较各行数据。本文将介绍一种方法,通过调用一个共享类方法来实现在DataGridView的特定列中绘制进度条,这种方法可以很容易地集成到任何DataGridView中。

使用代码

本项目以简单的方式展示了如何实现截图中的网格功能。根据是否显示目标指示器(由CheckBox1的状态决定),可以调用以下方法:

以下是一个处理DataGridView的CellPainting事件的代码示例:

Private Sub DataGridView1_CellPainting(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewCellPaintingEventArgs) Handles DataGridView1.CellPainting ' 避免绘制超出数据区域的行或列 If e.RowIndex < 0 OrElse e.ColumnIndex < 0 Then Exit Sub ' 检查是否正在绘制百分比列 If e.ColumnIndex <> Columns.Percent Then Exit Sub ' 获取数据行 Dim oRow As DataSet1.DataRow = DirectCast(DataGridView1.Rows(e.RowIndex).DataBoundItem, DataRowView).Row ' 告诉DataGridView将处理绘制单元格 e.Handled = True ' 根据百分比值选择条形颜色 Dim oColor As Drawing.Color = Color.Green If CheckBox1.Checked AndAlso oRow.percent < _ciTarget Then oColor = Color.Red End If ' 绘制带有条形的单元格 If CheckBox1.Checked Then Bar.PintaDegradado(oColor, e, oRow.percent, _ciTarget, Color.Orange) Else Bar.PintaDegradado(oColor, e, oRow.percent) End If End Sub

以下是Bar类代码,用于绘制DataGridView单元格中的条形:

Public Class Bar Public Shared Sub PintaDegradado(ByVal oColor As Drawing.Color, ByVal e As DataGridViewCellPaintingEventArgs) Bar.PintaDegradado(oColor, e, -1) End Sub Public Shared Sub PintaDegradado(ByVal oColor As Drawing.Color, ByVal e As DataGridViewCellPaintingEventArgs, ByVal iPorcentaje As Integer) Dim aCol As Drawing.Color() = {oColor} Dim aPor As Integer() = {iPorcentaje} If iPorcentaje = -1 Then Dim aPorN As Integer() = {} Bar.PintaDegradado(aCol, e, aPorN) Else Bar.PintaDegradado(aCol, e, aPor) End If End Sub Public Shared Sub PintaDegradado(ByVal oColor As Drawing.Color, ByVal e As DataGridViewCellPaintingEventArgs, ByVal iPorcentaje As Integer, ByVal iObjetivo As Integer, ByVal oColorObjetivo As Drawing.Color) Dim aCol As Drawing.Color() = {oColor, oColorObjetivo} Dim aPor As Integer() = {iPorcentaje, iObjetivo} Bar.PintaDegradado(aCol, e, aPor) End Sub Private Shared Sub PintaDegradado(ByVal aColores As Drawing.Color(), ByVal e As DataGridViewCellPaintingEventArgs, ByVal aPorcentajes As Integer()) ' 声明画刷和颜色数组 Dim oPin1 As Drawing2D.LinearGradientBrush = Nothing Dim oPin2 As Drawing2D.LinearGradientBrush = Nothing Dim oPinO As Drawing2D.LinearGradientBrush = Nothing Dim oColor As Drawing.Color = aColores(0) ' 处理任何异常 Try ' 获取单元格矩形 Dim oCelda As New Rectangle(e.CellBounds.X - 1, e.CellBounds.Y - 1, e.CellBounds.Width, e.CellBounds.Height) ' 调试百分比数组 For iC As Integer = 0 To aPorcentajes.Length - 1 If aPorcentajes(iC) > 100 Then aPorcentajes(iC) = 100 Next ' 声明矩形。 Dim oRect1 As Rectangle Dim oRect2 As Rectangle Dim oObj As Rectangle Dim oFond As Rectangle Dim oCuad As Rectangle = Nothing Dim oBorder As Rectangle ' 声明百分比变量 Dim iPorcentaje As Integer = 0 Dim bPor As Boolean = False ' 检测是否传递了百分比 If aPorcentajes.Length > 0 Then bPor = True iPorcentaje = aPorcentajes(0) If iPorcentaje > 0 Then ' 获取矩形和画刷以显示百分比指示器。 oRect1 = New Rectangle(oCelda.X + 4, oCelda.Y + 4, Math.Round(((oCelda.Width - 7) * iPorcentaje * 0.01) + 0.49), Math.Round((oCelda.Height - 8) / 2)) If oRect1.Width > oCelda.Width - 7 Then oRect1.Width = oCelda.Width - 7 oRect2 = New Rectangle(oCelda.X + 4, oRect1.Bottom - 1, oRect1.Width, (oCelda.Height - 6) - oRect1.Height) oFond = New Rectangle(oCelda.X + 4, oCelda.Y + 4, oCelda.Width - 7, oCelda.Height - 7) oPin1 = New Drawing2D.LinearGradientBrush(oRect1, Color.White, Color.FromArgb(180, oColor), Drawing2D.LinearGradientMode.Vertical) oPin2 = New Drawing2D.LinearGradientBrush(oRect2, oColor, Color.FromArgb(70, oColor), Drawing2D.LinearGradientMode.Vertical) End If If aPorcentajes.Length > 1 Then ' 获取矩形和画刷以显示目标指示器 Dim iObj As Integer = aPorcentajes(1) Dim iPos As Integer = oCelda.X + 4 + Math.Round(((oCelda.Width - 7) * iObj * 0.01) + 0.49) Dim iIni As Integer = iPos - 20 If iIni < oCelda.X + 4 Then iIni = oCelda.X + 4 oObj = New Rectangle(iIni, oCelda.Y + 2, iPos - iIni, oCelda.Height - 4) oPinO = New Drawing2D.LinearGradientBrush(oObj, Drawing.Color.FromArgb(0, aColores(1)), aColores(1), Drawing2D.LinearGradientMode.Horizontal) End If End If ' 获取边框矩形 oCuad = New Rectangle(oCelda.X + 3, oCelda.Y + 3, oCelda.Width - 6, oCelda.Height - 6) Else ' 获取矩形和画刷以填充单元格(没有百分比) oRect1 = New Rectangle(oCelda.X + 1, oCelda.Y + 1, oCelda.Width - 1, Math.Round(oCelda.Height / 2)) oRect2 = New Rectangle(oCelda.X + 1, oRect1.Bottom - 1, oCelda.Width - 1, oCelda.Height - oRect1.Height) oFond = New Rectangle(oCelda.X + 1, oCelda.Y + 1, oCelda.Width - 1, oCelda.Height) oPin1 = New Drawing2D.LinearGradientBrush(oRect1, Color.White, Color.FromArgb(180, oColor), Drawing2D.LinearGradientMode.Vertical) oPin2 = New Drawing2D.LinearGradientBrush(oRect2, oColor, Color.FromArgb(70, oColor), Drawing2D.LinearGradientMode.Vertical) End If ' 绘制单元格背景 e.PaintBackground(e.CellBounds, True) If bPor Then e.Graphics.DrawRectangle(Pens.DimGray, oCuad) End If ' 绘制玻璃条 If oPin1 IsNot Nothing Then e.Graphics.FillRectangle(Brushes.White, oFond) e.Graphics.FillRectangle(oPin1, oRect1) e.Graphics.FillRectangle(oPin2, oRect2) End If ' 绘制目标指示器 If oPinO IsNot Nothing Then e.Graphics.FillRectangle(oPinO, oObj) End If ' 绘制单元格内容 e.PaintContent(oCelda) e.Paint(oCelda, DataGridViewPaintParts.Border) e.Handled = True Catch ex As Exception Debug.Print(ex.Message) Finally ' 释放所有资源 If oPin1 IsNot Nothing Then oPin1.Dispose() oPin1 = Nothing End If If oPin2 IsNot Nothing Then oPin2.Dispose() oPin2 = Nothing End If If oPinO IsNot Nothing Then oPinO.Dispose() oPinO = Nothing End If End Try End Sub End Class
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485