In this article I will explain with an example, how to merge multiple Header Columns (Cells) in DataGridView in Windows Forms (WinForms) application using C# and VB.Net.
There is no direct way to merge multiple Header Columns (Cells) in DataGridView and hence this article will illustrate how to achieve the same by drawing a Rectangle over the existing Header Columns (Cells) in DataGridView using C# and VB.Net.
Form Design
The Form consists of a DataGridView control. The DataGridView has been assigned a Paint event handler.
Populating the DataGridView
Inside the Form Load event handler, the DataGridView is populated with data by making use of a dynamic DataTable with some records.
C#
private void Form1_Load(object sender, EventArgs e)
{
DataTable dt = new DataTable();
dt.Columns.AddRange(new DataColumn[4] { new DataColumn("Id", typeof(int)),
new DataColumn("Name", typeof(string)),
new DataColumn("City", typeof(string)),
new DataColumn("Country",typeof(string)) });
dt.Rows.Add(1, "John Hammond", "Chicago", "United States");
dt.Rows.Add(2, "Mudassar Khan", "Mumbai", "India");
dt.Rows.Add(3, "Suzanne Mathews", "Paris", "France");
dt.Rows.Add(4, "Robert Schidner", "Moscow", "Russia");
this.dataGridView1.DataSource = dt;
}
VB.Net
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Dim dt As DataTable = New DataTable()
dt.Columns.AddRange(New DataColumn(3) {New DataColumn("Id", GetType(Integer)), New DataColumn("Name", GetType(String)), New DataColumn("City", GetType(String)), New DataColumn("Country", GetType(String))})
dt.Rows.Add(1, "John Hammond", "Chicago", "United States")
dt.Rows.Add(2, "Mudassar Khan", "Mumbai", "India")
dt.Rows.Add(3, "Suzanne Mathews", "Paris", "France")
dt.Rows.Add(4, "Robert Schidner", "Moscow", "Russia")
Me.dataGridView1.DataSource = dt
End Sub
Merging multiple Header Columns (Cells) in DataGridView
Inside the Paint event handler, first the coordinates i.e. X and Y position and the width of the Header Columns (Cells) to be merged is determined using the GetCellDisplayRectangle function of the DataGridView.
Then a Rectangle is drawn over the Header Columns (Cells) to be merged using the coordinates and dimensions determined earlier.
Finally, the Text is drawn over the Rectangle.
C#
private void dataGridView1_Paint(object sender, PaintEventArgs e)
{
//Offsets to adjust the position of the merged Header.
int heightOffset = -5;
int widthOffset = -2;
int xOffset = 0;
int yOffset = 4;
//Index of Header column from where the merging will start.
int columnIndex = 2;
//Number of Header columns to be merged.
int columnCount = 2;
//Get the position of the Header Cell.
Rectangle headerCellRectangle = dataGridView1.GetCellDisplayRectangle(columnIndex, 0, true);
//X coordinate of the merged Header Column.
int xCord = headerCellRectangle.Location.X + xOffset;
//Y coordinate of the merged Header Column.
int yCord = headerCellRectangle.Location.Y - headerCellRectangle.Height + yOffset;
//Calculate Width of merged Header Column by adding the widths of all Columns to be merged.
int mergedHeaderWidth = dataGridView1.Columns[columnIndex].Width + dataGridView1.Columns[columnIndex + columnCount - 1].Width + widthOffset;
//Generate the merged Header Column Rectangle.
Rectangle mergedHeaderRect = new Rectangle(xCord, yCord, mergedHeaderWidth, headerCellRectangle.Height + heightOffset);
//Draw the merged Header Column Rectangle.
e.Graphics.FillRectangle(new SolidBrush(Color.White), mergedHeaderRect);
//Draw the merged Header Column Text.
e.Graphics.DrawString("Address", dataGridView1.ColumnHeadersDefaultCellStyle.Font, Brushes.Black, xCord + 2, yCord + 3);
}
VB.Net
Private Sub dataGridView1_Paint(ByVal sender As Object, ByVal e As PaintEventArgs) Handles dataGridView1.Paint
'Offsets to adjust the position of the merged Header.
Dim heightOffset As Integer = -5
Dim widthOffset As Integer = -2
Dim xOffset As Integer = 0
Dim yOffset As Integer = 4
'Index of Header column from where the merging will start.
Dim columnIndex As Integer = 2
'Number of Header columns to be merged.
Dim columnCount As Integer = 2
'Get the position of the Header Cell.
Dim headerCellRectangle As Rectangle = dataGridView1.GetCellDisplayRectangle(columnIndex, 0, True)
'X coordinate of the merged Header Column.
Dim xCord As Integer = (headerCellRectangle.Location.X + xOffset)
'Y coordinate of the merged Header Column.
Dim yCord As Integer = ((headerCellRectangle.Location.Y - headerCellRectangle.Height) + yOffset)
'Calculate Width of merged Header Column by adding the widths of all Columns to be merged.
Dim mergedHeaderWidth As Integer = (dataGridView1.Columns(columnIndex).Width + (dataGridView1.Columns((columnIndex + (columnCount - 1))).Width + widthOffset))
'Generate the merged Header Column Rectangle.
Dim mergedHeaderRect As Rectangle = New Rectangle(xCord, yCord, mergedHeaderWidth, (headerCellRectangle.Height + heightOffset))
'Draw the merged Header Column Rectangle.
e.Graphics.FillRectangle(New SolidBrush(Color.White), mergedHeaderRect)
'Draw the merged Header Column Text.
e.Graphics.DrawString("Address", dataGridView1.ColumnHeadersDefaultCellStyle.Font, Brushes.Black, (xCord + 2), (yCord + 3))
End Sub
Screenshots
DataGridView without Merged Header Columns (Cells)
DataGridView with Merged Header Columns (Cells)
Downloads