65.9K
CodeProject 正在变化。 阅读更多。
Home

DataGridView 中的条形图

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.79/5 (39投票s)

2010年6月4日

CPOL
viewsIcon

92739

downloadIcon

4506

如何在 DataGridView 中显示条形图

引言

有时,以图形方式显示 DataGridView 中一列的值对用户来说很有用,以便轻松比较行。这是一个通过仅从 DataGridViewCellPainting 事件调用共享类方法来实现此功能的示例,正如我在我的博客 http://ensamblareficiente.blogspot.com (西班牙语) 中描述的那样。

Using the Code

该项目以简单的方式展示了如何使屏幕截图网格正常工作。

这是基于我们是否要显示目标指示器(CheckBox1 的状态告诉我们这一点)调用的方法

Private Sub DataGridView1_CellPainting(ByVal sender As Object, _
        ByVal e As System.Windows.Forms.DataGridViewCellPaintingEventArgs) _
        Handles DataGridView1.CellPainting
    '   Avoids rows or columns out of data area
    If e.RowIndex < 0 OrElse e.ColumnIndex < 0 Then Exit Sub

    '   Checks if it's painting percent column
    If e.ColumnIndex <> Columns.Percent Then Exit Sub

    '   Get data row
    Dim oRow As DataSet1.DataRow = _
        DirectCast(DataGridView1.Rows(e.RowIndex).DataBoundItem, DataRowView).Row

    '   Tells to DataGridView that we will take care of painting cell
    e.Handled = True

    '   Selects bar color based on percent value.
    Dim oColor As Drawing.Color = Color.Green
    If CheckBox1.Checked AndAlso oRow.percent < _ciTarget Then oColor = Color.Red

    '   Draws cell with bar
    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 类的代码

''' <summary>
''' Draws a bar in a DatGridView cell.
''' </summary>
''' <remarks></remarks>
Public Class Bar

    ''' <summary>
    ''' Draws a glass bar into a cell
    ''' </summary>
    ''' <param name="oColor">Color of the bar.</param>
    ''' <param name="e">CellPainting event's parameters</param>
    ''' <remarks></remarks>
    Public Shared Sub PintaDegradado(ByVal oColor As Drawing.Color, _
                  ByVal e As DataGridViewCellPaintingEventArgs)
        Bar.PintaDegradado(oColor, e, -1)
    End Sub

    ''' <summary>
    ''' Draws a partial glass bar into a cell
    ''' </summary>
    ''' <param name="oColor">Color of the bar.</param>
    ''' <param name="e">CellPainting event's parameters</param>
    ''' <param name="iPorcentaje">Percent value to represent.</param>
    ''' <remarks></remarks>
    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

    ''' <summary>
    ''' Draws a partial glass bar into a cell with target indicator.
    ''' </summary>
    ''' <param name="oColor">Color of the bar.</param>
    ''' <param name="e">CellPainting event's parameters</param>
    ''' <param name="iPorcentaje">Percent value to represent.</param>
    ''' <param name="iObjetivo">Target to show.</param>
    ''' <param name="oColorObjetivo">Target indicator color.</param>
    ''' <remarks></remarks>
    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

    ''' <summary>
    ''' Does the hard job
    ''' </summary>
    ''' <param name="aColores">Color array to use.</param>
    ''' <param name="e">CellPainting event's parameters</param>
    ''' <param name="aPorcentajes">Percent array to show. It can be one or two. 
    ''' First shows bar percent and second shows target percent. 
    ''' If only one percent is passed and it's cero, 
    ''' it will fill all cell width with the glass bar.</param>
    ''' <remarks></remarks>
    Private Shared Sub PintaDegradado(ByVal aColores As Drawing.Color(), _
	ByVal e As DataGridViewCellPaintingEventArgs, ByVal aPorcentajes As Integer())

        '   Declares brushes and color array
        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)

        '   Handles any exception
        Try
            '   Gets cell rectangle
            Dim oCelda As New Rectangle(e.CellBounds.X - 1, e.CellBounds.Y - 1, _
		e.CellBounds.Width, e.CellBounds.Height)

            '   Debugs percent array
            For iC As Integer = 0 To aPorcentajes.Length - 1
                If aPorcentajes(iC) > 100 Then aPorcentajes(iC) = 100
            Next

            '   Declares rectangles.
            Dim oRect1 As Rectangle             ' Glass upper rect.
            Dim oRect2 As Rectangle             ' Glass lower rect.
            Dim oObj As Rectangle               ' Target rect.
            Dim oFond As Rectangle              ' Background rect.
            Dim oCuad As Rectangle = Nothing    ' Border rect.

            '   Declares percent variable
            Dim iPorcentaje As Integer = 0
            Dim bPor As Boolean = False

            '   Detects if percent(s) is/are passed
            '   One percent indicates only value percent.
            '   Two percents indicate value and target percent.
            If aPorcentajes.Length > 0 Then
                bPor = True
                iPorcentaje = aPorcentajes(0)

                If iPorcentaje > 0 Then

                    '   Gets rectangles and brushes for percent indicator.
                    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

                    '   Get rectangles and brushes for target indicator
                    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

                '   Get border rectangle
                oCuad = New Rectangle(oCelda.X + 3, oCelda.Y + 3, oCelda.Width - 6, _
			oCelda.Height - 6)
            Else

                '   Gets rectangles and brushes to fill cell (no percents)
                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

            '   Paints cell background
            e.PaintBackground(e.CellBounds, True)
            If bPor Then
                e.Graphics.DrawRectangle(Pens.DimGray, oCuad)
            End If

            '   Paints glass bar
            If oPin1 IsNot Nothing Then
                e.Graphics.FillRectangle(Brushes.White, oFond)
                e.Graphics.FillRectangle(oPin1, oRect1)
                e.Graphics.FillRectangle(oPin2, oRect2)
            End If

            '   Paints target indicator
            If oPinO IsNot Nothing Then
                e.Graphics.FillRectangle(oPinO, oObj)
            End If

            '   Paints cell contents
            e.PaintContent(oCelda)
            e.Paint(oCelda, DataGridViewPaintParts.Border)
            e.Handled = True
        Catch ex As Exception
            Debug.Print(ex.Message)
        Finally

            '   Dispose all resources
            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

关注点

这段代码展示了如何绘制玻璃效果条:两个渐变矩形就完成了这项工作。它还展示了如何处理 DataGridView 的单元格绘制操作。这些条形图是动态绘制的,因此实时数据更新会实时显示。这允许显示实时进度条。

历史

  • 2010 年 6 月 4 日:原始版本
  • 2010 年 8 月 24 日:文章已更新
© . All rights reserved.