0
0

C# DGV スクロール時に結合セルの描画がおかしくなる問題への対処

Last updated at Posted at 2023-11-23

画面外にある領域のセル幅は取得できないので、
Invalidateで再描画の強制をする必要があった。

その為、スクロールイベントにInvalidate() の呼び出し処理を加えた。

意味わからんと思うので、詳細は下記。

private void SampleDataGridView_Scroll(object sender, ScrollEventArgs e)
{
    SampleDataGridView_Scroll.Invalidate();
}

前提として、結合セルの作り方。

Excel 結合セルの作り方

image1.png
一般にイメージされやすい結合セル。

C# DataGridView 結合セルの作り方

image2.png

セルを伸ばして疑似的に結合セルを作る。
となりのセルは描画しない。

ぶつかった問題

セルを伸ばす際には、
同じ行内にあるセルの幅を足し合わせて、伸ばす横幅を求める。

image3.png

ただ実は、画面の可視領域内に入っている分のセル幅しか取得できない。
image4.png

だから、スクロールするたびにセルの幅を取得させるために
スクロールイベントにInvalidate() の呼び出し処理を加えた

以上。

細かい話

Invalidateをしなくても実は、
スクロールするたびにセルの幅を取得はされている。

結合セルの作成処理は一般的にCellPaintingに作られると思う

private void MyDataGridView_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
    // 省略 : 疑似的な結合セルの作成処理
}

ブレークポイントを置いてスクロールをすると、
CellPainting呼ばれているのがわかるはず。

ではなぜ、
Invalidateするのかというと、
DGVのキャッシュを削除してくれるからである。
これで、最新の情報でセルの描画がされる。

スクロールをした際にキャッシュから、
過去のセルの描画情報が拾われてきている、というのが根本の原因。

DGVのキャッシュは、VirtualMode プロパティを trueに設定 とかで管理できたりするらしい。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0