Here's a screen shot of what you will get by using this code:
Introduction
This code came out as an elaboration of Custom draw datagridviewcolumnheader (like Excel 2007) by Andy32.
Normally, a DataGridView
control won't allow you to set a background image for its column headers. This code will do that, in a very easy way.
I made this just to simplify what has already been done by the original author.
I supplied an image, which is a stripe (1 pixel wide), to use a background. You don't need more, because it will be stretched to fill the whole columnheader
.
Now, since it is a semi-transparent PNG, you'll see the color of the Columheader
. By doing so, you won't need to supply a different image for each colour you'd like to paint your Headers - you just change the ColumnHeadersDefaultCellStyle.BackColor
property and you're done.
It couldn't be any easier, I think.
Background
As the original article, this code illustrates how to custom draw a DataGridView
Column Headers.
My version is just an optimized version of the original, with much less code and a small improvement (the mentioned small-sized transparent image that lets the underlying color be seen through).
There is very little code: an enumeration (a set of grouped constants), a method and its call inside an event of the DataGridView
. Nothing more than this!!
Oh, well, I forgot to mention that a little bit of initialization code is required (here I do that directly in the Form's Load
event handler, but you can put it into a method and call that method from the Load
event).
Private Sub frmMain_Load(ByVal sender As Object, ByVal e As EventArgs) _
Handles Me.Load
With dgvData.ColumnHeadersDefaultCellStyle
.Alignment = DataGridViewContentAlignment.MiddleCenter
.BackColor = Color.DarkRed
.ForeColor = Color.Gold
.Font = New Font(.Font.FontFamily, .Font.Size, _
.Font.Style Or FontStyle.Bold, GraphicsUnit.Point)
End With
For i As Int32 = 0 To 20
Dim arrStrings As String()
arrStrings = New String() _
{ _
i.ToString, "Text " & i.ToString, i.ToString, _
"Text " & i.ToString, i.ToString _
}
dgvData.Rows.Add(arrStrings)
arrStrings = Nothing
Next i
End Sub
Just to put some data into the DataGridView
and to set the Color
for its column headers.
Using the Code
Inside the CellPainting
event of the DataGridView
, call the supplied GridDrawCustomHeaderColumns
method (feel free to shorten the name, if you want):
Private Sub dgvData_CellPainting(ByVal sender As Object, _
ByVal e As DataGridViewCellPaintingEventArgs) _
Handles dgvData.CellPainting
If e.RowIndex = -1 Then
GridDrawCustomHeaderColumns(dgvData, e, _
My.Resources.Button_Gray_Stripe_01_050, _
DGVHeaderImageAlignments.Stretch)
End If
End Sub
The code above will override the normal CellPainting
with the code contained in our method:
Private Sub GridDrawCustomHeaderColumns(ByVal dgv As DataGridView, _
ByVal e As DataGridViewCellPaintingEventArgs, ByVal img As Image, _
ByVal Style As DGVHeaderImageAlignments)
Dim gr As Graphics = e.Graphics
gr.FillRectangle( _
New SolidBrush(dgv.ColumnHeadersDefaultCellStyle.BackColor), _
e.CellBounds)
If img IsNot Nothing Then
Select Case Style
Case DGVHeaderImageAlignments.FillCell
gr.DrawImage( _
img, e.CellBounds.X, e.CellBounds.Y, _
e.CellBounds.Width, e.CellBounds.Height)
Case DGVHeaderImageAlignments.SingleCentered
gr.DrawImage(img, _
((e.CellBounds.Width - img.Width) \ 2) + _
e.CellBounds.X, _
((e.CellBounds.Height - img.Height) \ 2) + _
e.CellBounds.Y, _
img.Width, img.Height)
Case DGVHeaderImageAlignments.SingleLeft
gr.DrawImage(img, e.CellBounds.X, _
((e.CellBounds.Height - img.Height) \ 2) + _
e.CellBounds.Y, _
img.Width, img.Height)
Case DGVHeaderImageAlignments.SingleRight
gr.DrawImage(img, _
(e.CellBounds.Width - img.Width) + _
e.CellBounds.X, _
((e.CellBounds.Height - img.Height) \ 2) + _
e.CellBounds.Y, _
img.Width, img.Height)
Case DGVHeaderImageAlignments.Tile
Dim br As New TextureBrush_
(img, Drawing2D.WrapMode.Tile)
gr.FillRectangle(br, e.ClipBounds)
Case Else
gr.DrawImage( _
img, e.CellBounds.X, e.CellBounds.Y, _
e.ClipBounds.Width, e.CellBounds.Height)
End Select
End If
If e.Value Is Nothing Then
e.Handled = True
Return
End If
Using sf As New StringFormat
With sf
Select Case dgv.ColumnHeadersDefaultCellStyle.Alignment
Case DataGridViewContentAlignment.BottomCenter
.Alignment = StringAlignment.Center
.LineAlignment = StringAlignment.Far
Case DataGridViewContentAlignment.BottomLeft
.Alignment = StringAlignment.Near
.LineAlignment = StringAlignment.Far
Case DataGridViewContentAlignment.BottomRight
.Alignment = StringAlignment.Far
.LineAlignment = StringAlignment.Far
Case DataGridViewContentAlignment.MiddleCenter
.Alignment = StringAlignment.Center
.LineAlignment = StringAlignment.Center
Case DataGridViewContentAlignment.MiddleLeft
.Alignment = StringAlignment.Near
.LineAlignment = StringAlignment.Center
Case DataGridViewContentAlignment.MiddleRight
.Alignment = StringAlignment.Far
.LineAlignment = StringAlignment.Center
Case DataGridViewContentAlignment.TopCenter
.Alignment = StringAlignment.Center
.LineAlignment = StringAlignment.Near
Case DataGridViewContentAlignment.TopLeft
.Alignment = StringAlignment.Near
.LineAlignment = StringAlignment.Near
Case DataGridViewContentAlignment.TopRight
.Alignment = StringAlignment.Far
.LineAlignment = StringAlignment.Near
End Select
StringFormatFlags.FitBlackBox
.HotkeyPrefix = Drawing.Text.HotkeyPrefix.None
.Trimming = StringTrimming.None
End With
With dgv.ColumnHeadersDefaultCellStyle
gr.DrawString(e.Value.ToString, .Font, _
New SolidBrush(.ForeColor), e.CellBounds, sf)
End With
End Using
e.Handled = True
End Sub
So, what it does, basically is to:
Draw the background color, overlay an image over it, draw the text.
The way it aligns text is how you would draw the text on any other control: check how user wants the text to be aligned and operate accordingly with the StringFormat
object you'll use in combination with the DrawString
method.
There's two properties to do this: Alignment
(horizontally) and LineAlignment
(vertically); and three values Near
(Left or Up), Far
(Right or Down), and Center
(Middle).
The combination of these properties with their values gives the nine possible alignments for a text.
The way it draws the image can be tricky, so...
... you'll notice a section, in the above code, delimited by two "all asterisks" comment lines.
That's room for improvements (surely due to my misinterpretation of the DrawImage
method).
I hope that other programmers will find this code useful as per their needs.
Let me know how you make this code better.
History
- 9th March, 2009: Initial post