The recommended way to hide or modify cell border style is to code the CellPainting
event.
Don't worry, no actual painting is required. All you need to do is set a few fields in the e.AdvancedBorderStyle
parameter.
Here is an example:

Note the 'vertically merged' look of of the cells in the 3rd column; same for the 'horizontally merged' cells at the bottom. Also the double border of a cell in the 5th column.
private void dataGridView1_CellPainting(object sender,
DataGridViewCellPaintingEventArgs e)
{
if (e.ColumnIndex == 2 && e.RowIndex == 6)
e.AdvancedBorderStyle.Right = DataGridViewAdvancedCellBorderStyle.None;
if (e.ColumnIndex == 2 && e.RowIndex == 1)
e.AdvancedBorderStyle.Bottom = DataGridViewAdvancedCellBorderStyle.None;
if (e.ColumnIndex == 4 && e.RowIndex == 4)
{
e.AdvancedBorderStyle.All = DataGridViewAdvancedCellBorderStyle.InsetDouble;
e.AdvancedBorderStyle.Bottom = DataGridViewAdvancedCellBorderStyle.Single;
}
}
Note that hiding borders is rather straight forward : Simply hide the right or the bottom border; other borderstyles require some trial and error (or a deeper understanding ;-)
Here I first set the style for all sides but as it paints the botton white (at least that's what I think it does) I then set the botton border back to single.
You may want to streamline the way the checks are done; this is just a simple example.
Update:
Here is a code to make the merging more dynamic: Use the mergeCells
function to mark a cell for merging or un-merging with its right or bottom neighbour:
private void mergeCells(DataGridViewCell cell, bool mergeH, bool mergeV)
{
string m = "";
if (mergeH) m += "R"; // merge horizontally by hiding the right border line
if (mergeV) m += "B"; // merge vertically by hiding the bottom border line
cell.Tag = m == "" ? null : m;
}
The CellPainting
now looks like this:
private void customDGV1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
if (e.ColumnIndex < 0 || e.RowIndex < 0) return;
DataGridViewCell cell = ((DataGridView)sender)[e.ColumnIndex, e.RowIndex];
if (cell.Tag == null) return;
string hide = cell.Tag.ToString();
if (hide.Contains("R"))
e.AdvancedBorderStyle.Right = DataGridViewAdvancedCellBorderStyle.None;
else
e.AdvancedBorderStyle.Right = DataGridViewAdvancedCellBorderStyle.Single;
if (hide.Contains("B"))
e.AdvancedBorderStyle.Bottom = DataGridViewAdvancedCellBorderStyle.None;
else
e.AdvancedBorderStyle.Bottom = DataGridViewAdvancedCellBorderStyle.Single;
}
Update 2:
If you want to apply this to the ColumnHeaders
you need to turn off dgv.EnableHeadersViualStyles
first..