画面外にある領域のセル幅は取得できないので、
Invalidateで再描画の強制をする必要があった。
その為、スクロールイベントにInvalidate() の呼び出し処理を加えた。
意味わからんと思うので、詳細は下記。
private void SampleDataGridView_Scroll(object sender, ScrollEventArgs e)
{
SampleDataGridView_Scroll.Invalidate();
}
前提として、結合セルの作り方。
Excel 結合セルの作り方
C# DataGridView 結合セルの作り方
セルを伸ばして疑似的に結合セルを作る。
となりのセルは描画しない。
ぶつかった問題
セルを伸ばす際には、
同じ行内にあるセルの幅を足し合わせて、伸ばす横幅を求める。
ただ実は、画面の可視領域内に入っている分のセル幅しか取得できない。
だから、スクロールするたびにセルの幅を取得させるために
スクロールイベントにInvalidate() の呼び出し処理を加えた
以上。
細かい話
Invalidateをしなくても実は、
スクロールするたびにセルの幅を取得はされている。
結合セルの作成処理は一般的にCellPaintingに作られると思う
private void MyDataGridView_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
// 省略 : 疑似的な結合セルの作成処理
}
ブレークポイントを置いてスクロールをすると、
CellPainting呼ばれているのがわかるはず。
ではなぜ、
Invalidateするのかというと、
DGVのキャッシュを削除してくれるからである。
これで、最新の情報でセルの描画がされる。
スクロールをした際にキャッシュから、
過去のセルの描画情報が拾われてきている、というのが根本の原因。
DGVのキャッシュは、VirtualMode プロパティを trueに設定 とかで管理できたりするらしい。