How to Merge Cells in DataGridView

Edited by

If you still use the built-in WinForms.NET DataGridView control as your primary control for display of data in your applications, then you have most likely faced the issue of needing to merge cells in DataGridView to reduce duplication or display a long text field across multiple columns:

How to merge cells in DataGridView

Unfortunately, this intrinsic .NET control does not provide you with any built-in features to merge cells, but you can imitate cell merging with DataGridView's events, methods and properties. In this article we will consider two well-known solutions to the problem of merging cells in WinForms DataGridView and analyze their pros and cons.

How to merge DataGridView cells by removing cell borders

In many cases the tabular data you display in WinForms DataGridView comes from relational databases. The tables we visualize in DataGridView may contain repeated field values inside a column, and you may want to merge them into one big cell for better visual representation on the screen.

It is relatively easy to find solutions in which DataGridView cells are merged in columns automatically. The idea of this approach is to blank out repeated cell values on the screen and remove the corresponding borders of DataGridView cells belonging to one merged cell dynamically. DataGridView provides convenient tools to do that – the OnCellFormatting and OnCellPainting methods which you can override. As an alternative, you can inherit the DataGridViewTextBoxCell class and override its GetFormattedValue and Paint methods. The following thread on the MSDN social network suggests several implementations of this idea:

Merge datagridview row and column cells

Perhaps, the most useable solution in that thread is the DataGridViewMergedTextBoxColumn class posted by Felice Ferri. This approach allows you to merge DataGridView cells vertically only in particular columns but not in every column of the DataGridView. Even if the columns in DataGridView are autogenerated when you bind it to a data source, you can still replace the required autogenerated columns with columns in which cells with repeated values are merged automatically using a code snippet like this:

var col = new DataGridViewMergedTextBoxColumn();

const string field = "Fruit";

col.HeaderText = field;
col.Name = field;
col.DataPropertyName = field;

int colidx = dataGridView1.Columns[field].Index;
dataGridView1.Columns.Remove(field);
dataGridView1.Columns.Insert(colidx, col);

Felice published a basic version of the DataGridViewMergedTextBoxColumn class for VB.NET on MSDN, but we have amended it and converted to C#. You can download the full example of how to merge cells in DataGridView in C# from this website using this direct link.

Unfortunately, the original implementation of the DataGridViewMergedTextBoxColumn class does not draw the borders in the merged cells correctly. First, the user will see the unneeded top border in the very first merged cell. Second, the horizontal grid lines will look like jagged lines when they intersect the vertical grid line at the right in the column with merged cells:

Problems with grid lines in DataGridView with cells merged vertically

To correct this problem, we need to use the following code snippet that sets only the bottom cell border when required instead of setting the top and bottom borders in the original implementation:

if (rowIndex < this.DataGridView.Rows.Count - 1)
{
  if (IsRepeatedCellValue(rowIndex + 1, this.ColumnIndex))
  {
    advancedBorderStyle.Bottom = DataGridViewAdvancedCellBorderStyle.None;
  }
}

The IsRepeatedCellValue function can be also simplified if we replace the complex check with the static Object.Equals() call that processes both reference and value types as required.

Even if we correct these minor problems, there are still two serious drawbacks in the suggested approach that may prevent us from using it in production code for customers.

The first big problem of this approach is that we still deal with normal cells on intersections of rows and columns – even if we hide their visible texts on the fly by overriding the GetFormattedValue method. This means that your users will wonder when they click somewhere in the middle or bottom of such a merged cell because they will see the blue selection rectangle that is "less" than the whole clicked merged cell:

Problem with selection of merged cells in DataGridView

The second serious problem is related to the case when you need to merge cells vertically in two or more DataGridView columns. If we had one more column with fruit suppliers in our test DataGridView and we wanted to merge cells in the Supplier and Fruit columns to see what fruits are supplied by every company by countries, we would expect to see a picture like this:

Merge cells vertically in DataGridView columns – proper merging

As you can see, if Company 1 and Company 2 supply grape, we should have two separate cells with the "Grape" text belonging to these two companies. The same must be the case for bananas supplied by companies #3 and #4. However, if we use the DataGridViewMergedTextBoxColumn class to implement what we need, we get the following unsatisfactory result of merging DataGridView cells independently in the columns:

Merge cells vertically in DataGridView columns – improper merging

Note also that you cannot specify the vertical alignment for texts in cells "merged" this way. The text of these DataGridView merged cells will be always top-aligned, though sometimes you may need to center them vertically.

Merging DataGridView cells with custom drawing

Another popular way to merge cells in DataGridView is redefining the Paint procedure of the DataGridViewTextBoxCell class to draw cells of a bigger size. One of the threads on CodeGuru Forums contains an example of how to merge DataGridView cells in rows:

Merge DataGridView cells in rows

This looks good as a static screen and even allows you to specify any horizontal and vertical alignment for the texts in merged cells in the DataGridView. But the main drawback of this approach is that you cannot select these merged cells – neither with the mouse nor with the keyboard. The keyboard navigation in the DataGridView becomes chaotic if you use the cursor movement keys on your keyboard.

Add to this that using custom drawing to repaint DataGridView cells makes the whole control drawing significantly slower. This becomes noticeable while you are resizing a form together with a DataGridView with cells merged horizontally this way, even if we have 2 or 3 cells merged horizontally in the viewport. And this also slows down the scrolling in the DatGridView, which is slow enough by default (to find out more, read the article Why is DataGridView Slow at Scrolling, Rendering, Filtering and Populating? on this website).

Cell merging in a DataGridView alternative, iGrid.NET

As you can see, WinForms DataGridView does not support cell merging out of the box. Even the rich set of DataGridView members does not allow you to implement a viable substitution for true merged cells you could use in real-world applications. If you need to merge cells in DataGridView, perhaps it is time to consider an alternative grid control with native cell merging capabilities such as our iGrid.NET control.

10Tec iGrid for .NET allows you to merge individual cells using the simple SpanRows and SpanCols cell properties. In addition to this manual way of merging cells, you can use methods like MergeCellsInCols to merge cells with repeated values in columns automatically. The MergeCellsInCols method is free from the drawbacks of the DataGridViewMergedTextBoxColumn class and similar solutions described above. It takes into account the specified column hierarchy and even allows you to assign various cell styles to merged cells created automatically to format them with colors, fonts, and the like. iGrid merged cells are integrated seamlessly into the traditional keyboard navigation model and all mouse-based selection operations, like drag select in multiselect mode. Even sorting and grouping are allowed in iGrid if they do not lead to breaking existing merged cells (or you can dynamically remove cell merges before sorting/grouping to allow them with one call like the UnmergeAllCells method). All this allows you to integrate merged cells with other features of iGrid like tree grid to implement sophisticated interfaces like the following example of the project management tool in the form of a Gantt chart:

DataGridView alternative with merged cells to implement a Gantt chart

The next time you need to merge cells in DataGridView, consider 10Tec iGrid as an alternative solution. Visit the product's home page to find out more about other features of our WinForms grid control:

More about the iGrid.NET features »