vb.netimagewinformsgraphicsdatagridview

why event datagridview RowPostPaint output image in row header becomes blurry in vb.net


I'm Trying to use event datagridview RowPostPaint but output image in row header becomes blurry and there is a white color on each side of the in image with vb.net.

If you look at the screenhot, the result of a good image appears in the picturebox, how can I have the same result as the picturebox. Or something is wrong with my code.

Please Guide me

Thanks

Public Class Form1

    Private _source As New BindingSource()
    Private _person As List(Of person) = Nothing

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        _person = New List(Of person)()
        _person.Add(New person With {
            .ID = 1,
            .Name = "Tridip"
        })
        _person.Add(New person With {
            .ID = 2,
            .Name = "Sujit"
        })
        _person.Add(New person With {
            .ID = 3,
            .Name = "Arijit"
        })
        _source.DataSource = _person
        DataGridView1.DataSource = _source

    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(imageList1.Images(0))
        Dim myIcon As Icon = Icon.FromHandle(myBitmap.GetHicon())

        Dim graphics As Graphics = e.Graphics

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

        'Set x/y position - As the center of the RowHeaderCell
        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
End Class


Public Class person
    Public Property ID As Integer
    Public Property Name As String
End Class


screenhot

checklist

update code

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(imageList1.Images(0))
        Dim myIcon As Icon = Icon.FromHandle(myBitmap.GetHicon())

        Dim graphics As Graphics = e.Graphics

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

        'Set x/y position - As the center of the RowHeaderCell
        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)
        graphics.DrawImage(myBitmap, rectangle)
    End Sub

result from update code

result from update code

result answer from @dr.null

result answer from @dr.null


Solution

  • It appears that you have inserted the 28x28 PNG image into the ImageList with its default properties set. The image is resized and resampled based on the ColorDepth and ImageSize properties. As a result, the image becomes smaller and of lower quality.

    You don't need to have the image in an ImageList. include it in your project's Resources to keep it as is and set the relevant Graphics properties that produce high-quality shrinking and transformation.

    In your project's Properties, open the resources designer and drop the image. In the code, declare a class variable of type Bitmap and assign the image to it. Implement the grid's CellPainting event as follows...

    Public Class Form1
        Private ReadOnly checkMarkImage As Bitmap
    
        Sub New()
            InitializeComponent()
            checkMarkImage = My.Resources.CheckMark
        End Sub
    
       Private Sub DataGridView1_CellPainting(
           sender As Object,
           e As DataGridViewCellPaintingEventArgs) Handles _
           DataGridView1.CellPainting
           Dim dgv = DirectCast(sender, DataGridView)
    
           e.Paint(e.ClipBounds, DataGridViewPaintParts.All)
    
           If e.RowIndex >= 0 AndAlso
               e.ColumnIndex < 0 AndAlso
               e.RowIndex <> DataGridView1.NewRowIndex AndAlso
               String.IsNullOrEmpty(dgv.Rows(e.RowIndex).ErrorText) Then
               Dim gs = e.Graphics.Save()
               Dim sz = DataGridView1.RowTemplate.Height - 4 ' Change as needed...
               Dim srcRect = New Rectangle(Point.Empty, checkMarkImage.Size)
               Dim destRect = New Rectangle(
                   e.CellBounds.Right - sz - 1,
                   e.CellBounds.Y + (e.CellBounds.Height - sz) \ 2,
                   sz, sz)
    
               ' High-quality shrinking if needed...
               e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic
               ' Note the white checkmark with and without this one...
               e.Graphics.CompositingQuality = CompositingQuality.HighQuality
               e.Graphics.DrawImage(checkMarkImage, destRect, srcRect, GraphicsUnit.Pixel)
               e.Graphics.Restore(gs)
               e.Handled = True
           End If
       End Sub
    End Class