vb.netwinformsdatagridviewrowheaderdatagridrowheader

How to add different colour icons/images to the Row Header of a DataGridView


How to add different colour icons/images PNG Transparent to DataGridView row header in VB.NET?

Is it possible to provide a different color each row in the header row of DataGridView or is there another solution with DataGridView Column Image or else. is there any other solution just fill a different color only because my image file is Transparent png ?

Private Table1 As DataTable

Private Sub createdatatable()
    'Dim Table1 As DataTable
    Table1 = New DataTable("TableName")
    Dim column1 As DataColumn = New DataColumn("Column1")
    column1.DataType = System.Type.GetType("System.String")
    Dim column2 As DataColumn = New DataColumn("Column2")
    column2.DataType = System.Type.GetType("System.Int32")
    Dim column3 As DataColumn = New DataColumn("Column3")
    column3.DataType = System.Type.GetType("System.Int32")
    Table1.Columns.Add(column1)
    Table1.Columns.Add(column2)
    Table1.Columns.Add(column3)
    Dim Row1 As DataRow
    Dim Row2 As DataRow
    Dim Row3 As DataRow
    Row1 = Table1.NewRow()
    Row2 = Table1.NewRow()
    Row3 = Table1.NewRow()
    Row1.Item("Column1") = "Item1"
    Row1.Item("Column2") = 44
    Row1.Item("Column3") = 99
    Row2.Item("Column1") = "Item2"
    Row2.Item("Column2") = 50
    Row2.Item("Column3") = 70
    Row3.Item("Column1") = "Item3"
    Row3.Item("Column2") = 75
    Row3.Item("Column3") = 85
    Table1.Rows.Add(Row1)
    Table1.Rows.Add(Row2)
    Table1.Rows.Add(Row3)
    ' Repeat for other rows
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    createdatatable()
    DataGridView1.DataSource = Table1
End Sub

Private Sub DataGridView1_RowPostPaint(sender As Object, e As DataGridViewRowPostPaintEventArgs) Handles DataGridView1.RowPostPaint
    'Convert the image to icon, in order to load it in the row header column
    Dim myBitmap As New Bitmap(My.Resources.money)
    Dim myIcon As Icon = Icon.FromHandle(myBitmap.GetHicon())

    Dim graphics As Graphics = e.Graphics

    'Set Image dimension - User's choice
    Dim iconHeight As Integer = 14
    Dim iconWidth As Integer = 14

    'Set x/y position - As the center of the RowHeaderCell
    'INSTANT VB WARNING: Instant VB cannot determine whether both operands of this division are integer types - if they are then you should use the VB integer division operator:
    Dim xPosition As Integer = e.RowBounds.X + (DataGridView1.RowHeadersWidth / 2)
    Dim yPosition As Integer = e.RowBounds.Y + ((DataGridView1.Rows(e.RowIndex).Height - iconHeight) \ 2)

    Dim rectangle As New Rectangle(xPosition, yPosition, iconWidth, iconHeight)
    graphics.DrawIcon(myIcon, rectangle)

End Sub

Current result:
ICON IN ROW HEADER DATAGRIDVIEW

Image used:
icons/images PNG Transparent

The desired result of each image's different colors

The desired result of each image's different colors


Solution

  • Consider implementing the CellPainting event instead to control which paint parts to paint before drawing anything else. The parts defined in the DataGridViewPaintParts enum.

    Override the Onload method or implement the Load event to create the data source, bind the control, and create a color array.

    Private colors As Color()
    
    Protected Overrides Sub OnLoad(e As EventArgs)
        MyBase.OnLoad(e)
    
        colors = {Color.Red, Color.Green, Color.Orange, Color.Black}
    
        Dim Table1 = New DataTable("TableName")
    
        Table1.Columns.AddRange({
            New DataColumn("Column1", GetType(String)),
            New DataColumn("Column2", GetType(Integer)),
            New DataColumn("Column3", GetType(Integer))
        })
    
        Table1.Rows.Add("Item1", 44, 99)
        Table1.Rows.Add("Item2", 50, 70)
        Table1.Rows.Add("Item3", 75, 85)
    
        DataGridView1.RowTemplate.Height = 48
        DataGridView1.RowHeadersWidth = 48
        DataGridView1.DataSource = Table1
    End Sub
    

    In the CellPainting event, call the e.Paint(...) method and select which parts the base should paint, pick a color from the array to create a SolidBrush used to fill an ellipse as a background of your image. Lastly, draw the image within the ellipse rectangle.

    For example:

    Private Sub DataGridView1_CellPainting(
                    sender As Object,
                    e As DataGridViewCellPaintingEventArgs) _
                    Handles DataGridView1.CellPainting
        If e.RowIndex >= 0 AndAlso e.ColumnIndex = -1 AndAlso
            e.RowIndex <> DataGridView1.NewRowIndex Then
    
            'Option 1: Resizable image. Zoom effect.
            'Dim sz = Math.Min(e.CellBounds.Width, e.CellBounds.Height) - 6
            'Dim ellipseRect = New Rectangle(
            '        e.CellBounds.X + (e.CellBounds.Width - sz) \ 2,
            '        e.CellBounds.Y + (e.CellBounds.Height - sz) \ 2,
            '        sz, sz)
            'Dim imgRect = Rectangle.Inflate(ellipseRect, -3, 3)
    
    
            'Option 2: Fixed size. Change as needed.
            'Dim ellipseSize = 32            
            'Dim ellipseRect = New Rectangle(
            '    e.CellBounds.X + (e.CellBounds.Width - ellipseSize) \ 2,
            '    e.CellBounds.Y + (e.CellBounds.Height - ellipseSize) \ 2,
            '    ellipseSize, ellipseSize)
            'Dim imgSize = 24 ' or = ellipseSize
            'Dim imgRect = New Rectangle(
            '    ellipseRect.X + (ellipseRect.Width - imgSize) \ 2,
            '    ellipseRect.Y + (ellipseRect.Height - imgSize) \ 2,
            '    imgSize, imgSize)
    
    
            'Option 3: Size based on the RowTemplate.Height property.
            Dim ellipseSize = DataGridView1.RowTemplate.Height - 3
            Dim ellipseRect = New Rectangle(
                    e.CellBounds.X + (e.CellBounds.Width - ellipseSize) \ 2,
                    e.CellBounds.Y + (e.CellBounds.Height - ellipseSize) \ 2,
                    ellipseSize, ellipseSize)
            Dim imgSize = ellipseSize ' Or smaller...
            Dim imgRect = New Rectangle(
                ellipseRect.X + (ellipseRect.Width - imgSize) \ 2,
                ellipseRect.Y + (ellipseRect.Height - imgSize) \ 2,
                imgSize, imgSize)
            Dim colorIndex = e.RowIndex Mod colors.Length
            Dim g = e.Graphics
            Dim gs = g.Save()
    
            e.Paint(e.ClipBounds, DataGridViewPaintParts.Background Or
                    DataGridViewPaintParts.Border Or
                    DataGridViewPaintParts.SelectionBackground)
    
            Using bmp = My.Resources.Dollar,
                ellipseBrush = New SolidBrush(colors(colorIndex))
                g.SmoothingMode = SmoothingMode.AntiAlias
                g.FillEllipse(ellipseBrush, ellipseRect)
                g.InterpolationMode = InterpolationMode.HighQualityBicubic
                g.DrawImage(bmp, imgRect, 0, 0, bmp.Width, bmp.Height,
                            GraphicsUnit.Pixel)
            End Using
    
            g.Restore(gs)
            e.Handled = True
        End If
    End Sub
    

    76570839