it is possible to add multiple column headers to a datagridview??
For Example:
_________________________________________________________
| Kilometers | Summer | Winter |
|-------------- |--------------------|--------------------|
| From | To | Weekday | Weekend | Weekday | Weekend |
|-------|------ |----------|---------|----------|---------|
| 0 | 25 | $150 | $170 | $170 | $190 |
|_______|________________________________________________ |
Public Structure DGVMultiHeader
Public ReadOnly Text As String
Public BackColor As Color
Public ReadOnly FirstColumnIndex As Integer
Public ReadOnly LastColumnIndex As Integer
Sub New(ByVal text As String, ByVal firstColIndex As Integer, ByVal lastColIndex As Integer)
Me.Text = text
Me.FirstColumnIndex = firstColIndex
Me.LastColumnIndex = lastColIndex
Me.BackColor = Color.Empty
End Sub
End Structure
Public Class DGVMultiHeaderManager
Public ReadOnly Parent As DataGridView
Public ReadOnly MultiHeaders As New List(Of DGVMultiHeader)(0)
Sub New(ByVal dgv As DataGridView, ByVal multiheaders As IEnumerable(Of DGVMultiHeader))
Me.Parent = dgv
Me.MultiHeaders.AddRange(multiheaders)
Init()
End Sub
Sub Init()
Me.Parent.ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.EnableResizing
Me.Parent.ColumnHeadersHeight = Me.Parent.ColumnHeadersHeight * 2
Me.Parent.ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.BottomCenter
Me.Parent.ColumnHeadersDefaultCellStyle.WrapMode = DataGridViewTriState.False
'AddHandler Me.Parent.CellPainting, AddressOf DataGridView1_CellPainting
AddHandler Me.Parent.Paint, AddressOf DataGridView1_Paint
AddHandler Me.Parent.Scroll, AddressOf DataGridView1_Scroll
AddHandler Me.Parent.ColumnWidthChanged, AddressOf DataGridView1_ColumnWidthChanged
End Sub
Private Sub DataGridView1_ColumnWidthChanged(ByVal sender As Object, ByVal e As System.Windows.Forms.DataGridViewColumnEventArgs)
Dim rtHeader As Rectangle = Me.Parent.DisplayRectangle
rtHeader.Height = CInt(Me.Parent.ColumnHeadersHeight / 2)
Me.Parent.Invalidate(rtHeader)
End Sub
Private Sub DataGridView1_Scroll(ByVal sender As Object, ByVal e As System.Windows.Forms.ScrollEventArgs)
If e.ScrollOrientation = ScrollOrientation.HorizontalScroll Then
Dim rtHeader As Rectangle = Me.Parent.DisplayRectangle
rtHeader.Height = CInt(Me.Parent.ColumnHeadersHeight / 2)
Me.Parent.Invalidate(rtHeader)
End If
End Sub
Private Sub DataGridView1_Paint(ByVal sender As Object, ByVal e As System.Windows.Forms.PaintEventArgs)
Dim dgv = DirectCast(sender, DataGridView)
For Each grp In MultiHeaders
Dim lastDivWidth = dgv.Columns(grp.LastColumnIndex).DividerWidth
Dim multiWidth = 0I
For Index = grp.FirstColumnIndex To grp.LastColumnIndex
multiWidth += Me.Parent.Columns(Index).Width
Next
Dim firstRect = Me.Parent.GetCellDisplayRectangle(grp.FirstColumnIndex, -1, True)
' Dim firstHeaderCell = Me.Parent.Columns(grp.FirstIndex).HeaderCell
If firstRect.IsEmpty Then Continue For
Dim headerRect = New Rectangle(firstRect.Left + 1, _
firstRect.Y + 1, _
multiWidth - 2 - lastDivWidth, _
CInt(Me.Parent.ColumnHeadersHeight / 2) - 2)
Dim backcolor As Color = If(grp.BackColor.IsEmpty, dgv.ColumnHeadersDefaultCellStyle.BackColor, grp.BackColor)
e.Graphics.FillRectangle(New SolidBrush(backcolor), headerRect)
Dim format As New StringFormat()
format.Alignment = StringAlignment.Center
format.LineAlignment = StringAlignment.Center
e.Graphics.DrawString(grp.Text, dgv.ColumnHeadersDefaultCellStyle.Font, _
New SolidBrush(dgv.ColumnHeadersDefaultCellStyle.ForeColor), headerRect, format)
Next
End Sub
End Class
usage:
Dim headers As New List(Of Common.DGV.DGVMultiHeader)
headers.Add(New Common.DGV.DGVMultiHeader("Months", colJanuary.Index, colDecember.Index))
headers.Add(New Common.DGV.DGVMultiHeader("Total Expenses", colTransportation.Index, colHotels.Index))
Dim headerManager = New Common.DGV.DGVDoubleHeaders(myDatagridview, headers)