The (mian) problem is that you are trying to use the wrong row index to get the image size:
Rectangle cellRectangle = dataGridView1.GetCellDisplayRectangle(6, 0, true);
When you scroll, row zero is no longer displayed, so it doesn't strictly have any dimensions.
If you use the header row index (-1) then it appears to work for me:
private Image header = Image.FromFile(@"D:\Test Data\butHelp16x16.gif");
private void myDataGridView_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
if (e.RowIndex < 0)
{
Rectangle cellRectangle = myDataGridView.GetCellDisplayRectangle(0, -1, true);
e.PaintBackground(e.ClipBounds, true);
e.Graphics.DrawImage(header, cellRectangle.Location.X + 5, 1, 18, 18);
e.Handled = true;
}
}
However, horizontal scrolling is still a problem, because the header cell dimensions change as it scrolls, and the image gets "chopped up".
To get round that, you need to invalidate the header cell every time you scroll:
private void myDataGridView_Scroll(object sender, ScrollEventArgs e)
{
myDataGridView.InvalidateCell(myDataGridView.Columns[0].HeaderCell);
}
[edit]
BTW: Don't create Bitmap items willy-nilly - they are a scarce resource, and you need to Dispose of them properly when you are finished. Creating them anew each time you get a Cell Paint event is going to crash your app with an "out of memory" exception pretty quickly!
[/edit]