The DataGridView does not have any support for merging cells. You can custom paint content across cells, but apart from that you would have to do a lot of work and custom coding to produce merged editable cells.
It is nice to see that people keep asking question on this issue and the small fraction of code I provided was helpful to some of you. But this is only small part of custom coding to get really nice formated and merged datagridview... Anyways I dont think that I might be very helpful, since in many instances you need to figure it out how to make things in a way you want, but I can only provide small tips how to solve these kind of questions:
Shailendra;
In you paint event before you paint the row you can check whether row is select or no. If yes then paint it to blue if not then paint it in white and so on. Look at the code bellow:
Dim
fnt As New Font("Arial", 10, FontStyle.Bold, GraphicsUnit.Point) Dim rct1 As New Rectangle((DataGridView1.GetColumnDisplayRectangle(2, True).X), (DataGridView1.GetColumnDisplayRectangle(2, True).Y + DataGridView1.Columns(2).HeaderCell.ContentBounds.Height + 8), DataGridView1.GetColumnDisplayRectangle(2, True).Width - 1, (DataGridView1.GetRowDisplayRectangle((DataGridView1.Rows.Count - 1), True).Top - DataGridView1.GetRowDisplayRectangle((DataGridView1.Rows.Count - 1), True).Height)) e.Graphics.FillRectangle(Brushes.White, rct1) e.Graphics.DrawString("VERTICAL" & vbCrLf & "TEXT 3rd MERGED COLUMN", fnt, Brushes.Black, rct1) Dim rct As Rectangle = DataGridView1.GetRowDisplayRectangle(3, True) rct.Height -= 1 Dim s As SizeF = e.Graphics.MeasureString("HORINZONTAL TEXT", DataGridView1.Font) Dim lefts As Integer = (rct.Width / 2) - (s.Width / 2) Dim tops As Integer = rct.Top + ((rct.Height / 2) - (s.Height / 2)) If DataGridView1.Rows(DataGridView1.CurrentRow.Index).Selected = True Thene.Graphics.FillRectangle(Brushes.Blue, rct) e.Graphics.DrawString("HORINZONTAL TEXT", fnt, Brushes.White, 2, tops) Else e.Graphics.FillRectangle(Brushes.White, rct) e.Graphics.DrawString("HORINZONTAL TEXT", fnt, Brushes.Black, 2, tops) End If
Irshad_ip:
Still I believe you should figure it on your own... It should be so easy just repleace all zeros(0) in rct1 to 2 (3rd) column and add another rectangle such as rct2 and do it same as rct1 just instead of 2 in your constructor put 3:
Dim fnt As New Font("Arial", 10, FontStyle.Bold, GraphicsUnit.Point) Dim rct1 As New Rectangle((DataGridView1.GetColumnDisplayRectangle(2, True).X), (DataGridView1.GetColumnDisplayRectangle(2, True).Y + DataGridView1.Columns(2).HeaderCell.ContentBounds.Height + 8), DataGridView1.GetColumnDisplayRectangle(2, True).Width - 1, (DataGridView1.GetRowDisplayRectangle((DataGridView1.Rows.Count - 1), True).Top - DataGridView1.GetRowDisplayRectangle((DataGridView1.Rows.Count - 1), True).Height)) Dim rct2 As New Rectangle((DataGridView1.GetColumnDisplayRectangle(3, True).X), (DataGridView1.GetColumnDisplayRectangle(3, True).Y + DataGridView1.Columns(3).HeaderCell.ContentBounds.Height + 8), DataGridView1.GetColumnDisplayRectangle(3, True).Width - 1, (DataGridView1.GetRowDisplayRectangle((DataGridView1.Rows.Count - 1), True).Top - DataGridView1.GetRowDisplayRectangle((DataGridView1.Rows.Count - 1), True).Height)) e.Graphics.FillRectangle(Brushes.White, rct1) e.Graphics.DrawString("VERTICAL" & vbCrLf & "TEXT 3rd MERGED COLUMN", fnt, Brushes.Black, rct1) e.Graphics.FillRectangle(Brushes.White, rct2) e.Graphics.DrawString("VERTICAL" & vbCrLf & "TEXT 4th MERGED COLUMN", fnt, Brushes.Black, rct2) Dim rct As Rectangle = DataGridView1.GetRowDisplayRectangle(3, True) rct.Height -= 1 Dim s As SizeF = e.Graphics.MeasureString("HORINZONTAL TEXT", DataGridView1.Font) Dim lefts As Integer = (rct.Width / 2) - (s.Width / 2) Dim tops As Integer = rct.Top + ((rct.Height / 2) - (s.Height / 2)) e.Graphics.FillRectangle(Brushes.White, rct) e.Graphics.DrawString("HORINZONTAL TEXT", fnt, Brushes.Black, 2, tops)
Again, as I said before, you need to write really too many lines to get custom control. These are only small parts of codes that can only give you picture how should it look like. Any further coding you need to carry on your own... Anyways, hope this was helpful for both of you...
What i want is that i have 2 row headers in my control. say Rowheader0 and rowHeader1. i want to split the Rowheader0 in to two headers like x1 and x2.. Is it possible to do that
Create datagridview with i.e. 5 columns and 5 rows. Then add code below to paint event of DATAGRIDVIEW
Dim fnt As New Font("Arial", 10, FontStyle.Bold, GraphicsUnit.Point) Dim rct1 As New Rectangle((DataGridView1.GetColumnDisplayRectangle(0, True).X), (DataGridView1.GetColumnDisplayRectangle(0, True).Y + DataGridView1.Columns(0).HeaderCell.ContentBounds.Height + 8), DataGridView1.GetColumnDisplayRectangle(0, True).Width - 1, (DataGridView1.GetRowDisplayRectangle((DataGridView1.Rows.Count - 1), True).Top - DataGridView1.GetRowDisplayRectangle((DataGridView1.Rows.Count - 1), True).Height)) e.Graphics.FillRectangle(Brushes.White, rct1) e.Graphics.DrawString("VERTICAL" & vbCrLf & "TEXT", fnt, Brushes.Black, rct1) Dim rct As Rectangle = DataGridView1.GetRowDisplayRectangle(3, True) rct.Height -= 1 Dim s As SizeF = e.Graphics.MeasureString("HORINZONTAL TEXT", DataGridView1.Font) Dim lefts As Integer = (rct.Width / 2) - (s.Width / 2) Dim tops As Integer = rct.Top + ((rct.Height / 2) - (s.Height / 2)) e.Graphics.FillRectangle(Brushes.White, rct) e.Graphics.DrawString("HORINZONTAL TEXT", fnt, Brushes.Black, 2, tops)
From code above you will have first column as verticaly merged and 3rd row as horinzontaly merged. Hope this helps.... P.S. For custom coding you will need to figure it out....
Thank you for reply. But I would like to ask you additional question;
I was able to marge cells by Paint event but in my datagridview I have button and combobox columns. After painting event the controls in the rows are not visible but still they are accessible if user clicks on particular column. My question is how do I remove single combo box or button from a cell I tried to do it by
DataGridView1.Rows(3).Frozen =
True
DataGridView1.Rows(3).Cells(2).ReadOnly =
True
but it did not give results. Still there are controls attached to the cells.
In FlexGrid there is a property called Fixed Cols and Fixed Rows which will used for setting fixed rows and fixed Columns.(ie both primary and secondary). Is there any option is there in DataGridView(C# 2005). Or any idea abt how to do that
It is possible but you need to do tons of codes to achieve that. Painting event should only be ok if you want to merge content within control. Maybe the best for you would be to look for some custom components such as componentone true dbgrids or custom flex grid control. They might have solution for you....
MERGING CELLS IN DATAGRIDVIEW
Darren Thurman
The DataGridView does not have any support for merging cells. You can custom paint content across cells, but apart from that you would have to do a lot of work and custom coding to produce merged editable cells.
-mark
DataGridView Program Manager
Microsoft
This post is provided "as-is"
lgrainger
Hi
Ismar I want to merge the 3rd row in which only the 4th n 5th cell should be merged n not the whole row. how is it possible please help me.
farzade
Hello,
It is nice to see that people keep asking question on this issue and the small fraction of code I provided was helpful to some of you. But this is only small part of custom coding to get really nice formated and merged datagridview... Anyways I dont think that I might be very helpful, since in many instances you need to figure it out how to make things in a way you want, but I can only provide small tips how to solve these kind of questions:
Shailendra;
In you paint event before you paint the row you can check whether row is select or no. If yes then paint it to blue if not then paint it in white and so on. Look at the code bellow:
Dim
fnt As New Font("Arial", 10, FontStyle.Bold, GraphicsUnit.Point)Dim rct1 As New Rectangle((DataGridView1.GetColumnDisplayRectangle(2, True).X), (DataGridView1.GetColumnDisplayRectangle(2, True).Y + DataGridView1.Columns(2).HeaderCell.ContentBounds.Height + 8), DataGridView1.GetColumnDisplayRectangle(2, True).Width - 1, (DataGridView1.GetRowDisplayRectangle((DataGridView1.Rows.Count - 1), True).Top - DataGridView1.GetRowDisplayRectangle((DataGridView1.Rows.Count - 1), True).Height))
e.Graphics.FillRectangle(Brushes.White, rct1)
e.Graphics.DrawString("VERTICAL" & vbCrLf & "TEXT 3rd MERGED COLUMN", fnt, Brushes.Black, rct1)
Dim rct As Rectangle = DataGridView1.GetRowDisplayRectangle(3, True)
rct.Height -= 1
Dim s As SizeF = e.Graphics.MeasureString("HORINZONTAL TEXT", DataGridView1.Font)
Dim lefts As Integer = (rct.Width / 2) - (s.Width / 2)
Dim tops As Integer = rct.Top + ((rct.Height / 2) - (s.Height / 2))
If DataGridView1.Rows(DataGridView1.CurrentRow.Index).Selected = True Thene.Graphics.FillRectangle(Brushes.Blue, rct)
e.Graphics.DrawString("HORINZONTAL TEXT", fnt, Brushes.White, 2, tops)
Else
e.Graphics.FillRectangle(Brushes.White, rct)
e.Graphics.DrawString("HORINZONTAL TEXT", fnt, Brushes.Black, 2, tops)
End If Irshad_ip:
Still I believe you should figure it on your own... It should be so easy just repleace all zeros(0) in rct1 to 2 (3rd) column and add another rectangle such as rct2 and do it same as rct1 just instead of 2 in your constructor put 3:
Dim fnt As New Font("Arial", 10, FontStyle.Bold, GraphicsUnit.Point)Dim rct1 As New Rectangle((DataGridView1.GetColumnDisplayRectangle(2, True).X), (DataGridView1.GetColumnDisplayRectangle(2, True).Y + DataGridView1.Columns(2).HeaderCell.ContentBounds.Height + 8), DataGridView1.GetColumnDisplayRectangle(2, True).Width - 1, (DataGridView1.GetRowDisplayRectangle((DataGridView1.Rows.Count - 1), True).Top - DataGridView1.GetRowDisplayRectangle((DataGridView1.Rows.Count - 1), True).Height))
Dim rct2 As New Rectangle((DataGridView1.GetColumnDisplayRectangle(3, True).X), (DataGridView1.GetColumnDisplayRectangle(3, True).Y + DataGridView1.Columns(3).HeaderCell.ContentBounds.Height + 8), DataGridView1.GetColumnDisplayRectangle(3, True).Width - 1, (DataGridView1.GetRowDisplayRectangle((DataGridView1.Rows.Count - 1), True).Top - DataGridView1.GetRowDisplayRectangle((DataGridView1.Rows.Count - 1), True).Height))
e.Graphics.FillRectangle(Brushes.White, rct1)
e.Graphics.DrawString("VERTICAL" & vbCrLf & "TEXT 3rd MERGED COLUMN", fnt, Brushes.Black, rct1)
e.Graphics.FillRectangle(Brushes.White, rct2)
e.Graphics.DrawString("VERTICAL" & vbCrLf & "TEXT 4th MERGED COLUMN", fnt, Brushes.Black, rct2)
Dim rct As Rectangle = DataGridView1.GetRowDisplayRectangle(3, True)
rct.Height -= 1
Dim s As SizeF = e.Graphics.MeasureString("HORINZONTAL TEXT", DataGridView1.Font)
Dim lefts As Integer = (rct.Width / 2) - (s.Width / 2)
Dim tops As Integer = rct.Top + ((rct.Height / 2) - (s.Height / 2))
e.Graphics.FillRectangle(Brushes.White, rct)
e.Graphics.DrawString("HORINZONTAL TEXT", fnt, Brushes.Black, 2, tops)
Again, as I said before, you need to write really too many lines to get custom control. These are only small parts of codes that can only give you picture how should it look like. Any further coding you need to carry on your own... Anyways, hope this was helpful for both of you...
Happy coding
Boywonder0337
Hello sir,
Where should i write your given Merge cell code means in which event exactly
can u pass me any code to merge cells in datagridview
thnx in advance
Eric Wolz - MSFT
Hi ismar,
I am also having the same problem.. Will u please tell me how to merge cells in a datagridview..
How and what to do with that paint of method
Thanks in advance.
Any help is appreciated
Mark Groves
Dear ,
When I press the right arrow, The grid is not selecting the merged cells, it selects only first cell, bcoz it call each time
RowPostPaint event to paint merge cell .Bcoz of this it is not showing all selected merge cells,
Please help me When I press the right arrow,It shoulld select all merge cells
Thanks in advance
jazure
i would like to know that as well...
anyone an idea
Carlos G. Sarmiento
Hi thanks for ur reply..
What i want is that i have 2 row headers in my control. say Rowheader0 and rowHeader1. i want to split the Rowheader0 in to two headers like x1 and x2.. Is it possible to do that
Please share ur ideas..
Thanks in advance
Pramod V
Dear Sir,
When I press the right arrow, The grid is not selecting the merged cells, it selects only first cell, bcoz it call each time
RowPostPaint event to paint merge cell .Bcoz of this it is not showing all selected merge cells,
Please help me When I press the right arrow,It shoulld select all merge cells
Please pass me ur code to MErger cells in Datagridview.
Thanks in advance
BSSWinnipeg
Hello,
I was only able to manage to disable rows by putting
DataGridView.Rows(i).ReadOnly=true or DataGridView.Rows(i).Frozen=true
but stil there are controls within the cell.......
Tim Weaver
Hi here is what I did with my datagrid,
Create datagridview with i.e. 5 columns and 5 rows. Then add code below to paint event of DATAGRIDVIEW
Dim fnt As New Font("Arial", 10, FontStyle.Bold, GraphicsUnit.Point)Dim rct1 As New Rectangle((DataGridView1.GetColumnDisplayRectangle(0, True).X), (DataGridView1.GetColumnDisplayRectangle(0, True).Y + DataGridView1.Columns(0).HeaderCell.ContentBounds.Height + 8), DataGridView1.GetColumnDisplayRectangle(0, True).Width - 1, (DataGridView1.GetRowDisplayRectangle((DataGridView1.Rows.Count - 1), True).Top - DataGridView1.GetRowDisplayRectangle((DataGridView1.Rows.Count - 1), True).Height))
e.Graphics.FillRectangle(Brushes.White, rct1)
e.Graphics.DrawString("VERTICAL" & vbCrLf & "TEXT", fnt, Brushes.Black, rct1)
Dim rct As Rectangle = DataGridView1.GetRowDisplayRectangle(3, True)
rct.Height -= 1
Dim s As SizeF = e.Graphics.MeasureString("HORINZONTAL TEXT", DataGridView1.Font)
Dim lefts As Integer = (rct.Width / 2) - (s.Width / 2)
Dim tops As Integer = rct.Top + ((rct.Height / 2) - (s.Height / 2))
e.Graphics.FillRectangle(Brushes.White, rct)
e.Graphics.DrawString("HORINZONTAL TEXT", fnt, Brushes.Black, 2, tops)
From code above you will have first column as verticaly merged and 3rd row as horinzontaly merged. Hope this helps....
P.S. For custom coding you will need to figure it out....
Ismar
uAli
Hi there Mark
Thank you for reply. But I would like to ask you additional question;
I was able to marge cells by Paint event but in my datagridview I have button and combobox columns. After painting event the controls in the rows are not visible but still they are accessible if user clicks on particular column. My question is how do I remove single combo box or button from a cell I tried to do it by
DataGridView1.Rows(3).Frozen =
TrueDataGridView1.Rows(3).Cells(2).ReadOnly =
Truebut it did not give results. Still there are controls attached to the cells.
Peter Richard
Hi,
In FlexGrid there is a property called Fixed Cols and Fixed Rows which will used for setting fixed rows and fixed Columns.(ie both primary and secondary). Is there any option is there in DataGridView(C# 2005). Or any idea abt how to do that
Thanks in advance
Please Share ur ideas
Raymundo Chapa G
Hello,
It is possible but you need to do tons of codes to achieve that. Painting event should only be ok if you want to merge content within control. Maybe the best for you would be to look for some custom components such as componentone true dbgrids or custom flex grid control. They might have solution for you....
Regards,